diff --git a/tapestry-webresources/build.gradle b/tapestry-webresources/build.gradle
index 874cfef..775cdde 100644
--- a/tapestry-webresources/build.gradle
+++ b/tapestry-webresources/build.gradle
@@ -8,7 +8,8 @@
 
     testCompile project(":tapestry-runner")
     testCompile "org.gebish:geb-spock:${versions.geb}"
-
+    testCompile "org.spockframework:spock-tapestry:${versions.spock}"
+    
     testCompile "org.seleniumhq.selenium:selenium-java:${versions.selenium}", {
         exclude group: "org.eclipse.jetty"
     }
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/TypeScriptCompiler.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/TypeScriptCompiler.java
new file mode 100755
index 0000000..355aee1
--- /dev/null
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/TypeScriptCompiler.java
@@ -0,0 +1,76 @@
+package org.apache.tapestry5.internal.webresources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.tapestry5.ContentType;
+import org.apache.tapestry5.annotations.Path;
+import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.services.assets.ResourceDependencies;
+import org.apache.tapestry5.services.assets.ResourceTransformer;
+import org.mozilla.javascript.NativeObject;
+
+public class TypeScriptCompiler implements ResourceTransformer {
+  private final static Charset UTF8 = StandardCharsets.UTF_8;
+
+  private final RhinoExecutorPool executorPool;
+
+  @Override
+  public ContentType getTransformedContentType()
+  {
+      return InternalConstants.JAVASCRIPT_CONTENT_TYPE;
+  }
+
+  public TypeScriptCompiler(final OperationTracker tracker,
+      @Path("classpath:org/apache/tapestry5/webresources/internal/typescript.js") final Resource typescript)
+  {
+      this.executorPool = new RhinoExecutorPool(tracker, Arrays.<Resource> asList(typescript,
+          new ClasspathResource("org/apache/tapestry5/webresources/internal/invoke-typescript.js")));
+
+  }
+
+  private static String getString(final NativeObject object, final String key)
+  {
+      return object.get(key).toString();
+  }
+
+  @Override
+  public InputStream transform(final Resource source, final ResourceDependencies dependencies) throws IOException
+  {
+      InputStream is = null;
+      String content;
+  
+      try
+      {
+          is = source.openStream();
+          content = IOUtils.toString(is, UTF8);
+      } finally {
+          InternalUtils.close(is);
+      }
+  
+      RhinoExecutor executor = executorPool.get();
+  
+      try {
+  
+          NativeObject result = (NativeObject) executor.invokeFunction("transpile", content, source.toString());
+  
+          if (result.containsKey("exception")) {
+              throw new RuntimeException(getString(result, "exception"));
+          }
+  
+          return IOUtils.toInputStream(getString(result, "output"), UTF8);
+  
+        } finally {
+          executor.discard();
+        }
+
+   }
+}
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
index 7a716e4..c2adcad 100644
--- a/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
@@ -15,6 +15,7 @@
 import com.github.sommeri.less4j.LessCompiler;
 import com.github.sommeri.less4j.core.parser.AntlrException;
 import com.google.javascript.jscomp.CompilationLevel;
+
 import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.internal.webresources.*;
 import org.apache.tapestry5.ioc.MappedConfiguration;
@@ -63,7 +64,8 @@
 
     @Contribute(StreamableResourceSource.class)
     public static void provideCompilers(MappedConfiguration<String, ResourceTransformer> configuration, ResourceTransformerFactory factory,
-                                        @Autobuild CoffeeScriptCompiler coffeeScriptCompiler)
+                                        @Autobuild CoffeeScriptCompiler coffeeScriptCompiler,
+                                        @Autobuild final TypeScriptCompiler tsCompiler)
     {
         // contribution ids are file extensions:
 
@@ -75,6 +77,10 @@
         configuration.add("less",
                 factory.createCompiler("text/css", "Less", "CSS", new LessResourceTransformer(),
                         CacheMode.MULTIPLE_FILE));
+
+        configuration.add("ts",
+                factory.createCompiler("text/javascript", "TS", "JavaScript", tsCompiler,
+                        CacheMode.SINGLE_FILE));
     }
 
     @Contribute(ResourceMinimizer.class)
diff --git a/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/invoke-typescript.js b/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/invoke-typescript.js
new file mode 100644
index 0000000..fa18d6d
--- /dev/null
+++ b/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/invoke-typescript.js
@@ -0,0 +1,24 @@
+//https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
+function transpile(fileNames) {
+  var compilerOptions = {
+    noEmitOnError : true,
+    emitDecoratorMetadata: true,
+    experimentalDecorators: true,
+    newLine: 'LF',
+    noImplicitAny : true,
+    target : ts.ScriptTarget.ES5,
+    module : "AMD"
+  };
+  
+  var transpileOptions = {
+    compilerOptions : compilerOptions,
+    reportDiagnostics: false
+  };
+  
+  var result = ts.transpileModule(fileNames, transpileOptions);
+
+  return {
+    output : result.outputText
+  };
+
+}
diff --git a/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/typescript.js b/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/typescript.js
new file mode 100644
index 0000000..eb75ba8
--- /dev/null
+++ b/tapestry-webresources/src/main/resources/org/apache/tapestry5/webresources/internal/typescript.js
@@ -0,0 +1,97680 @@
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved. 
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0  
+ 
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
+MERCHANTABLITY OR NON-INFRINGEMENT. 
+ 
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+
+"use strict";
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var ts;
+(function (ts) {
+    // token > SyntaxKind.Identifer => token is a keyword
+    // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
+    var SyntaxKind;
+    (function (SyntaxKind) {
+        SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
+        SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
+        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
+        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
+        SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
+        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
+        // We detect and preserve #! on the first line
+        SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia";
+        // We detect and provide better error recovery when we encounter a git merge marker.  This
+        // allows us to edit files with git-conflict markers in them in a much more pleasant manner.
+        SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia";
+        // Literals
+        SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
+        SyntaxKind[SyntaxKind["StringLiteral"] = 9] = "StringLiteral";
+        SyntaxKind[SyntaxKind["JsxText"] = 10] = "JsxText";
+        SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 11] = "JsxTextAllWhiteSpaces";
+        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 12] = "RegularExpressionLiteral";
+        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 13] = "NoSubstitutionTemplateLiteral";
+        // Pseudo-literals
+        SyntaxKind[SyntaxKind["TemplateHead"] = 14] = "TemplateHead";
+        SyntaxKind[SyntaxKind["TemplateMiddle"] = 15] = "TemplateMiddle";
+        SyntaxKind[SyntaxKind["TemplateTail"] = 16] = "TemplateTail";
+        // Punctuation
+        SyntaxKind[SyntaxKind["OpenBraceToken"] = 17] = "OpenBraceToken";
+        SyntaxKind[SyntaxKind["CloseBraceToken"] = 18] = "CloseBraceToken";
+        SyntaxKind[SyntaxKind["OpenParenToken"] = 19] = "OpenParenToken";
+        SyntaxKind[SyntaxKind["CloseParenToken"] = 20] = "CloseParenToken";
+        SyntaxKind[SyntaxKind["OpenBracketToken"] = 21] = "OpenBracketToken";
+        SyntaxKind[SyntaxKind["CloseBracketToken"] = 22] = "CloseBracketToken";
+        SyntaxKind[SyntaxKind["DotToken"] = 23] = "DotToken";
+        SyntaxKind[SyntaxKind["DotDotDotToken"] = 24] = "DotDotDotToken";
+        SyntaxKind[SyntaxKind["SemicolonToken"] = 25] = "SemicolonToken";
+        SyntaxKind[SyntaxKind["CommaToken"] = 26] = "CommaToken";
+        SyntaxKind[SyntaxKind["LessThanToken"] = 27] = "LessThanToken";
+        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 28] = "LessThanSlashToken";
+        SyntaxKind[SyntaxKind["GreaterThanToken"] = 29] = "GreaterThanToken";
+        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 30] = "LessThanEqualsToken";
+        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 31] = "GreaterThanEqualsToken";
+        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 32] = "EqualsEqualsToken";
+        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 33] = "ExclamationEqualsToken";
+        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 34] = "EqualsEqualsEqualsToken";
+        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 35] = "ExclamationEqualsEqualsToken";
+        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 36] = "EqualsGreaterThanToken";
+        SyntaxKind[SyntaxKind["PlusToken"] = 37] = "PlusToken";
+        SyntaxKind[SyntaxKind["MinusToken"] = 38] = "MinusToken";
+        SyntaxKind[SyntaxKind["AsteriskToken"] = 39] = "AsteriskToken";
+        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 40] = "AsteriskAsteriskToken";
+        SyntaxKind[SyntaxKind["SlashToken"] = 41] = "SlashToken";
+        SyntaxKind[SyntaxKind["PercentToken"] = 42] = "PercentToken";
+        SyntaxKind[SyntaxKind["PlusPlusToken"] = 43] = "PlusPlusToken";
+        SyntaxKind[SyntaxKind["MinusMinusToken"] = 44] = "MinusMinusToken";
+        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 45] = "LessThanLessThanToken";
+        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 46] = "GreaterThanGreaterThanToken";
+        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 47] = "GreaterThanGreaterThanGreaterThanToken";
+        SyntaxKind[SyntaxKind["AmpersandToken"] = 48] = "AmpersandToken";
+        SyntaxKind[SyntaxKind["BarToken"] = 49] = "BarToken";
+        SyntaxKind[SyntaxKind["CaretToken"] = 50] = "CaretToken";
+        SyntaxKind[SyntaxKind["ExclamationToken"] = 51] = "ExclamationToken";
+        SyntaxKind[SyntaxKind["TildeToken"] = 52] = "TildeToken";
+        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 53] = "AmpersandAmpersandToken";
+        SyntaxKind[SyntaxKind["BarBarToken"] = 54] = "BarBarToken";
+        SyntaxKind[SyntaxKind["QuestionToken"] = 55] = "QuestionToken";
+        SyntaxKind[SyntaxKind["ColonToken"] = 56] = "ColonToken";
+        SyntaxKind[SyntaxKind["AtToken"] = 57] = "AtToken";
+        // Assignments
+        SyntaxKind[SyntaxKind["EqualsToken"] = 58] = "EqualsToken";
+        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 59] = "PlusEqualsToken";
+        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 60] = "MinusEqualsToken";
+        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 61] = "AsteriskEqualsToken";
+        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 62] = "AsteriskAsteriskEqualsToken";
+        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 63] = "SlashEqualsToken";
+        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 64] = "PercentEqualsToken";
+        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 65] = "LessThanLessThanEqualsToken";
+        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 66] = "GreaterThanGreaterThanEqualsToken";
+        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 67] = "GreaterThanGreaterThanGreaterThanEqualsToken";
+        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 68] = "AmpersandEqualsToken";
+        SyntaxKind[SyntaxKind["BarEqualsToken"] = 69] = "BarEqualsToken";
+        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 70] = "CaretEqualsToken";
+        // Identifiers
+        SyntaxKind[SyntaxKind["Identifier"] = 71] = "Identifier";
+        // Reserved words
+        SyntaxKind[SyntaxKind["BreakKeyword"] = 72] = "BreakKeyword";
+        SyntaxKind[SyntaxKind["CaseKeyword"] = 73] = "CaseKeyword";
+        SyntaxKind[SyntaxKind["CatchKeyword"] = 74] = "CatchKeyword";
+        SyntaxKind[SyntaxKind["ClassKeyword"] = 75] = "ClassKeyword";
+        SyntaxKind[SyntaxKind["ConstKeyword"] = 76] = "ConstKeyword";
+        SyntaxKind[SyntaxKind["ContinueKeyword"] = 77] = "ContinueKeyword";
+        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 78] = "DebuggerKeyword";
+        SyntaxKind[SyntaxKind["DefaultKeyword"] = 79] = "DefaultKeyword";
+        SyntaxKind[SyntaxKind["DeleteKeyword"] = 80] = "DeleteKeyword";
+        SyntaxKind[SyntaxKind["DoKeyword"] = 81] = "DoKeyword";
+        SyntaxKind[SyntaxKind["ElseKeyword"] = 82] = "ElseKeyword";
+        SyntaxKind[SyntaxKind["EnumKeyword"] = 83] = "EnumKeyword";
+        SyntaxKind[SyntaxKind["ExportKeyword"] = 84] = "ExportKeyword";
+        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 85] = "ExtendsKeyword";
+        SyntaxKind[SyntaxKind["FalseKeyword"] = 86] = "FalseKeyword";
+        SyntaxKind[SyntaxKind["FinallyKeyword"] = 87] = "FinallyKeyword";
+        SyntaxKind[SyntaxKind["ForKeyword"] = 88] = "ForKeyword";
+        SyntaxKind[SyntaxKind["FunctionKeyword"] = 89] = "FunctionKeyword";
+        SyntaxKind[SyntaxKind["IfKeyword"] = 90] = "IfKeyword";
+        SyntaxKind[SyntaxKind["ImportKeyword"] = 91] = "ImportKeyword";
+        SyntaxKind[SyntaxKind["InKeyword"] = 92] = "InKeyword";
+        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 93] = "InstanceOfKeyword";
+        SyntaxKind[SyntaxKind["NewKeyword"] = 94] = "NewKeyword";
+        SyntaxKind[SyntaxKind["NullKeyword"] = 95] = "NullKeyword";
+        SyntaxKind[SyntaxKind["ReturnKeyword"] = 96] = "ReturnKeyword";
+        SyntaxKind[SyntaxKind["SuperKeyword"] = 97] = "SuperKeyword";
+        SyntaxKind[SyntaxKind["SwitchKeyword"] = 98] = "SwitchKeyword";
+        SyntaxKind[SyntaxKind["ThisKeyword"] = 99] = "ThisKeyword";
+        SyntaxKind[SyntaxKind["ThrowKeyword"] = 100] = "ThrowKeyword";
+        SyntaxKind[SyntaxKind["TrueKeyword"] = 101] = "TrueKeyword";
+        SyntaxKind[SyntaxKind["TryKeyword"] = 102] = "TryKeyword";
+        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 103] = "TypeOfKeyword";
+        SyntaxKind[SyntaxKind["VarKeyword"] = 104] = "VarKeyword";
+        SyntaxKind[SyntaxKind["VoidKeyword"] = 105] = "VoidKeyword";
+        SyntaxKind[SyntaxKind["WhileKeyword"] = 106] = "WhileKeyword";
+        SyntaxKind[SyntaxKind["WithKeyword"] = 107] = "WithKeyword";
+        // Strict mode reserved words
+        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 108] = "ImplementsKeyword";
+        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 109] = "InterfaceKeyword";
+        SyntaxKind[SyntaxKind["LetKeyword"] = 110] = "LetKeyword";
+        SyntaxKind[SyntaxKind["PackageKeyword"] = 111] = "PackageKeyword";
+        SyntaxKind[SyntaxKind["PrivateKeyword"] = 112] = "PrivateKeyword";
+        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 113] = "ProtectedKeyword";
+        SyntaxKind[SyntaxKind["PublicKeyword"] = 114] = "PublicKeyword";
+        SyntaxKind[SyntaxKind["StaticKeyword"] = 115] = "StaticKeyword";
+        SyntaxKind[SyntaxKind["YieldKeyword"] = 116] = "YieldKeyword";
+        // Contextual keywords
+        SyntaxKind[SyntaxKind["AbstractKeyword"] = 117] = "AbstractKeyword";
+        SyntaxKind[SyntaxKind["AsKeyword"] = 118] = "AsKeyword";
+        SyntaxKind[SyntaxKind["AnyKeyword"] = 119] = "AnyKeyword";
+        SyntaxKind[SyntaxKind["AsyncKeyword"] = 120] = "AsyncKeyword";
+        SyntaxKind[SyntaxKind["AwaitKeyword"] = 121] = "AwaitKeyword";
+        SyntaxKind[SyntaxKind["BooleanKeyword"] = 122] = "BooleanKeyword";
+        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 123] = "ConstructorKeyword";
+        SyntaxKind[SyntaxKind["DeclareKeyword"] = 124] = "DeclareKeyword";
+        SyntaxKind[SyntaxKind["GetKeyword"] = 125] = "GetKeyword";
+        SyntaxKind[SyntaxKind["IsKeyword"] = 126] = "IsKeyword";
+        SyntaxKind[SyntaxKind["KeyOfKeyword"] = 127] = "KeyOfKeyword";
+        SyntaxKind[SyntaxKind["ModuleKeyword"] = 128] = "ModuleKeyword";
+        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 129] = "NamespaceKeyword";
+        SyntaxKind[SyntaxKind["NeverKeyword"] = 130] = "NeverKeyword";
+        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 131] = "ReadonlyKeyword";
+        SyntaxKind[SyntaxKind["RequireKeyword"] = 132] = "RequireKeyword";
+        SyntaxKind[SyntaxKind["NumberKeyword"] = 133] = "NumberKeyword";
+        SyntaxKind[SyntaxKind["ObjectKeyword"] = 134] = "ObjectKeyword";
+        SyntaxKind[SyntaxKind["SetKeyword"] = 135] = "SetKeyword";
+        SyntaxKind[SyntaxKind["StringKeyword"] = 136] = "StringKeyword";
+        SyntaxKind[SyntaxKind["SymbolKeyword"] = 137] = "SymbolKeyword";
+        SyntaxKind[SyntaxKind["TypeKeyword"] = 138] = "TypeKeyword";
+        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 139] = "UndefinedKeyword";
+        SyntaxKind[SyntaxKind["FromKeyword"] = 140] = "FromKeyword";
+        SyntaxKind[SyntaxKind["GlobalKeyword"] = 141] = "GlobalKeyword";
+        SyntaxKind[SyntaxKind["OfKeyword"] = 142] = "OfKeyword";
+        // Parse tree nodes
+        // Names
+        SyntaxKind[SyntaxKind["QualifiedName"] = 143] = "QualifiedName";
+        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 144] = "ComputedPropertyName";
+        // Signature elements
+        SyntaxKind[SyntaxKind["TypeParameter"] = 145] = "TypeParameter";
+        SyntaxKind[SyntaxKind["Parameter"] = 146] = "Parameter";
+        SyntaxKind[SyntaxKind["Decorator"] = 147] = "Decorator";
+        // TypeMember
+        SyntaxKind[SyntaxKind["PropertySignature"] = 148] = "PropertySignature";
+        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 149] = "PropertyDeclaration";
+        SyntaxKind[SyntaxKind["MethodSignature"] = 150] = "MethodSignature";
+        SyntaxKind[SyntaxKind["MethodDeclaration"] = 151] = "MethodDeclaration";
+        SyntaxKind[SyntaxKind["Constructor"] = 152] = "Constructor";
+        SyntaxKind[SyntaxKind["GetAccessor"] = 153] = "GetAccessor";
+        SyntaxKind[SyntaxKind["SetAccessor"] = 154] = "SetAccessor";
+        SyntaxKind[SyntaxKind["CallSignature"] = 155] = "CallSignature";
+        SyntaxKind[SyntaxKind["ConstructSignature"] = 156] = "ConstructSignature";
+        SyntaxKind[SyntaxKind["IndexSignature"] = 157] = "IndexSignature";
+        // Type
+        SyntaxKind[SyntaxKind["TypePredicate"] = 158] = "TypePredicate";
+        SyntaxKind[SyntaxKind["TypeReference"] = 159] = "TypeReference";
+        SyntaxKind[SyntaxKind["FunctionType"] = 160] = "FunctionType";
+        SyntaxKind[SyntaxKind["ConstructorType"] = 161] = "ConstructorType";
+        SyntaxKind[SyntaxKind["TypeQuery"] = 162] = "TypeQuery";
+        SyntaxKind[SyntaxKind["TypeLiteral"] = 163] = "TypeLiteral";
+        SyntaxKind[SyntaxKind["ArrayType"] = 164] = "ArrayType";
+        SyntaxKind[SyntaxKind["TupleType"] = 165] = "TupleType";
+        SyntaxKind[SyntaxKind["UnionType"] = 166] = "UnionType";
+        SyntaxKind[SyntaxKind["IntersectionType"] = 167] = "IntersectionType";
+        SyntaxKind[SyntaxKind["ParenthesizedType"] = 168] = "ParenthesizedType";
+        SyntaxKind[SyntaxKind["ThisType"] = 169] = "ThisType";
+        SyntaxKind[SyntaxKind["TypeOperator"] = 170] = "TypeOperator";
+        SyntaxKind[SyntaxKind["IndexedAccessType"] = 171] = "IndexedAccessType";
+        SyntaxKind[SyntaxKind["MappedType"] = 172] = "MappedType";
+        SyntaxKind[SyntaxKind["LiteralType"] = 173] = "LiteralType";
+        // Binding patterns
+        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 174] = "ObjectBindingPattern";
+        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 175] = "ArrayBindingPattern";
+        SyntaxKind[SyntaxKind["BindingElement"] = 176] = "BindingElement";
+        // Expression
+        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 177] = "ArrayLiteralExpression";
+        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 178] = "ObjectLiteralExpression";
+        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 179] = "PropertyAccessExpression";
+        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 180] = "ElementAccessExpression";
+        SyntaxKind[SyntaxKind["CallExpression"] = 181] = "CallExpression";
+        SyntaxKind[SyntaxKind["NewExpression"] = 182] = "NewExpression";
+        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 183] = "TaggedTemplateExpression";
+        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 184] = "TypeAssertionExpression";
+        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 185] = "ParenthesizedExpression";
+        SyntaxKind[SyntaxKind["FunctionExpression"] = 186] = "FunctionExpression";
+        SyntaxKind[SyntaxKind["ArrowFunction"] = 187] = "ArrowFunction";
+        SyntaxKind[SyntaxKind["DeleteExpression"] = 188] = "DeleteExpression";
+        SyntaxKind[SyntaxKind["TypeOfExpression"] = 189] = "TypeOfExpression";
+        SyntaxKind[SyntaxKind["VoidExpression"] = 190] = "VoidExpression";
+        SyntaxKind[SyntaxKind["AwaitExpression"] = 191] = "AwaitExpression";
+        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 192] = "PrefixUnaryExpression";
+        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 193] = "PostfixUnaryExpression";
+        SyntaxKind[SyntaxKind["BinaryExpression"] = 194] = "BinaryExpression";
+        SyntaxKind[SyntaxKind["ConditionalExpression"] = 195] = "ConditionalExpression";
+        SyntaxKind[SyntaxKind["TemplateExpression"] = 196] = "TemplateExpression";
+        SyntaxKind[SyntaxKind["YieldExpression"] = 197] = "YieldExpression";
+        SyntaxKind[SyntaxKind["SpreadElement"] = 198] = "SpreadElement";
+        SyntaxKind[SyntaxKind["ClassExpression"] = 199] = "ClassExpression";
+        SyntaxKind[SyntaxKind["OmittedExpression"] = 200] = "OmittedExpression";
+        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 201] = "ExpressionWithTypeArguments";
+        SyntaxKind[SyntaxKind["AsExpression"] = 202] = "AsExpression";
+        SyntaxKind[SyntaxKind["NonNullExpression"] = 203] = "NonNullExpression";
+        SyntaxKind[SyntaxKind["MetaProperty"] = 204] = "MetaProperty";
+        // Misc
+        SyntaxKind[SyntaxKind["TemplateSpan"] = 205] = "TemplateSpan";
+        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 206] = "SemicolonClassElement";
+        // Element
+        SyntaxKind[SyntaxKind["Block"] = 207] = "Block";
+        SyntaxKind[SyntaxKind["VariableStatement"] = 208] = "VariableStatement";
+        SyntaxKind[SyntaxKind["EmptyStatement"] = 209] = "EmptyStatement";
+        SyntaxKind[SyntaxKind["ExpressionStatement"] = 210] = "ExpressionStatement";
+        SyntaxKind[SyntaxKind["IfStatement"] = 211] = "IfStatement";
+        SyntaxKind[SyntaxKind["DoStatement"] = 212] = "DoStatement";
+        SyntaxKind[SyntaxKind["WhileStatement"] = 213] = "WhileStatement";
+        SyntaxKind[SyntaxKind["ForStatement"] = 214] = "ForStatement";
+        SyntaxKind[SyntaxKind["ForInStatement"] = 215] = "ForInStatement";
+        SyntaxKind[SyntaxKind["ForOfStatement"] = 216] = "ForOfStatement";
+        SyntaxKind[SyntaxKind["ContinueStatement"] = 217] = "ContinueStatement";
+        SyntaxKind[SyntaxKind["BreakStatement"] = 218] = "BreakStatement";
+        SyntaxKind[SyntaxKind["ReturnStatement"] = 219] = "ReturnStatement";
+        SyntaxKind[SyntaxKind["WithStatement"] = 220] = "WithStatement";
+        SyntaxKind[SyntaxKind["SwitchStatement"] = 221] = "SwitchStatement";
+        SyntaxKind[SyntaxKind["LabeledStatement"] = 222] = "LabeledStatement";
+        SyntaxKind[SyntaxKind["ThrowStatement"] = 223] = "ThrowStatement";
+        SyntaxKind[SyntaxKind["TryStatement"] = 224] = "TryStatement";
+        SyntaxKind[SyntaxKind["DebuggerStatement"] = 225] = "DebuggerStatement";
+        SyntaxKind[SyntaxKind["VariableDeclaration"] = 226] = "VariableDeclaration";
+        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 227] = "VariableDeclarationList";
+        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 228] = "FunctionDeclaration";
+        SyntaxKind[SyntaxKind["ClassDeclaration"] = 229] = "ClassDeclaration";
+        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 230] = "InterfaceDeclaration";
+        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 231] = "TypeAliasDeclaration";
+        SyntaxKind[SyntaxKind["EnumDeclaration"] = 232] = "EnumDeclaration";
+        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 233] = "ModuleDeclaration";
+        SyntaxKind[SyntaxKind["ModuleBlock"] = 234] = "ModuleBlock";
+        SyntaxKind[SyntaxKind["CaseBlock"] = 235] = "CaseBlock";
+        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 236] = "NamespaceExportDeclaration";
+        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 237] = "ImportEqualsDeclaration";
+        SyntaxKind[SyntaxKind["ImportDeclaration"] = 238] = "ImportDeclaration";
+        SyntaxKind[SyntaxKind["ImportClause"] = 239] = "ImportClause";
+        SyntaxKind[SyntaxKind["NamespaceImport"] = 240] = "NamespaceImport";
+        SyntaxKind[SyntaxKind["NamedImports"] = 241] = "NamedImports";
+        SyntaxKind[SyntaxKind["ImportSpecifier"] = 242] = "ImportSpecifier";
+        SyntaxKind[SyntaxKind["ExportAssignment"] = 243] = "ExportAssignment";
+        SyntaxKind[SyntaxKind["ExportDeclaration"] = 244] = "ExportDeclaration";
+        SyntaxKind[SyntaxKind["NamedExports"] = 245] = "NamedExports";
+        SyntaxKind[SyntaxKind["ExportSpecifier"] = 246] = "ExportSpecifier";
+        SyntaxKind[SyntaxKind["MissingDeclaration"] = 247] = "MissingDeclaration";
+        // Module references
+        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 248] = "ExternalModuleReference";
+        // JSX
+        SyntaxKind[SyntaxKind["JsxElement"] = 249] = "JsxElement";
+        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 250] = "JsxSelfClosingElement";
+        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 251] = "JsxOpeningElement";
+        SyntaxKind[SyntaxKind["JsxClosingElement"] = 252] = "JsxClosingElement";
+        SyntaxKind[SyntaxKind["JsxAttribute"] = 253] = "JsxAttribute";
+        SyntaxKind[SyntaxKind["JsxAttributes"] = 254] = "JsxAttributes";
+        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 255] = "JsxSpreadAttribute";
+        SyntaxKind[SyntaxKind["JsxExpression"] = 256] = "JsxExpression";
+        // Clauses
+        SyntaxKind[SyntaxKind["CaseClause"] = 257] = "CaseClause";
+        SyntaxKind[SyntaxKind["DefaultClause"] = 258] = "DefaultClause";
+        SyntaxKind[SyntaxKind["HeritageClause"] = 259] = "HeritageClause";
+        SyntaxKind[SyntaxKind["CatchClause"] = 260] = "CatchClause";
+        // Property assignments
+        SyntaxKind[SyntaxKind["PropertyAssignment"] = 261] = "PropertyAssignment";
+        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 262] = "ShorthandPropertyAssignment";
+        SyntaxKind[SyntaxKind["SpreadAssignment"] = 263] = "SpreadAssignment";
+        // Enum
+        SyntaxKind[SyntaxKind["EnumMember"] = 264] = "EnumMember";
+        // Top-level nodes
+        SyntaxKind[SyntaxKind["SourceFile"] = 265] = "SourceFile";
+        SyntaxKind[SyntaxKind["Bundle"] = 266] = "Bundle";
+        // JSDoc nodes
+        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 267] = "JSDocTypeExpression";
+        // The * type
+        SyntaxKind[SyntaxKind["JSDocAllType"] = 268] = "JSDocAllType";
+        // The ? type
+        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 269] = "JSDocUnknownType";
+        SyntaxKind[SyntaxKind["JSDocNullableType"] = 270] = "JSDocNullableType";
+        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 271] = "JSDocNonNullableType";
+        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 272] = "JSDocOptionalType";
+        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 273] = "JSDocFunctionType";
+        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 274] = "JSDocVariadicType";
+        SyntaxKind[SyntaxKind["JSDocComment"] = 275] = "JSDocComment";
+        SyntaxKind[SyntaxKind["JSDocTag"] = 276] = "JSDocTag";
+        SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 277] = "JSDocAugmentsTag";
+        SyntaxKind[SyntaxKind["JSDocClassTag"] = 278] = "JSDocClassTag";
+        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 279] = "JSDocParameterTag";
+        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 280] = "JSDocReturnTag";
+        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 281] = "JSDocTypeTag";
+        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 282] = "JSDocTemplateTag";
+        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 283] = "JSDocTypedefTag";
+        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 284] = "JSDocPropertyTag";
+        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 285] = "JSDocTypeLiteral";
+        // Synthesized list
+        SyntaxKind[SyntaxKind["SyntaxList"] = 286] = "SyntaxList";
+        // Transformation nodes
+        SyntaxKind[SyntaxKind["NotEmittedStatement"] = 287] = "NotEmittedStatement";
+        SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 288] = "PartiallyEmittedExpression";
+        SyntaxKind[SyntaxKind["CommaListExpression"] = 289] = "CommaListExpression";
+        SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 290] = "MergeDeclarationMarker";
+        SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 291] = "EndOfDeclarationMarker";
+        // Enum value count
+        SyntaxKind[SyntaxKind["Count"] = 292] = "Count";
+        // Markers
+        SyntaxKind[SyntaxKind["FirstAssignment"] = 58] = "FirstAssignment";
+        SyntaxKind[SyntaxKind["LastAssignment"] = 70] = "LastAssignment";
+        SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 59] = "FirstCompoundAssignment";
+        SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 70] = "LastCompoundAssignment";
+        SyntaxKind[SyntaxKind["FirstReservedWord"] = 72] = "FirstReservedWord";
+        SyntaxKind[SyntaxKind["LastReservedWord"] = 107] = "LastReservedWord";
+        SyntaxKind[SyntaxKind["FirstKeyword"] = 72] = "FirstKeyword";
+        SyntaxKind[SyntaxKind["LastKeyword"] = 142] = "LastKeyword";
+        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 108] = "FirstFutureReservedWord";
+        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 116] = "LastFutureReservedWord";
+        SyntaxKind[SyntaxKind["FirstTypeNode"] = 158] = "FirstTypeNode";
+        SyntaxKind[SyntaxKind["LastTypeNode"] = 173] = "LastTypeNode";
+        SyntaxKind[SyntaxKind["FirstPunctuation"] = 17] = "FirstPunctuation";
+        SyntaxKind[SyntaxKind["LastPunctuation"] = 70] = "LastPunctuation";
+        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
+        SyntaxKind[SyntaxKind["LastToken"] = 142] = "LastToken";
+        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
+        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
+        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
+        SyntaxKind[SyntaxKind["LastLiteralToken"] = 13] = "LastLiteralToken";
+        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 13] = "FirstTemplateToken";
+        SyntaxKind[SyntaxKind["LastTemplateToken"] = 16] = "LastTemplateToken";
+        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 27] = "FirstBinaryOperator";
+        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 70] = "LastBinaryOperator";
+        SyntaxKind[SyntaxKind["FirstNode"] = 143] = "FirstNode";
+        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 267] = "FirstJSDocNode";
+        SyntaxKind[SyntaxKind["LastJSDocNode"] = 285] = "LastJSDocNode";
+        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 276] = "FirstJSDocTagNode";
+        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 285] = "LastJSDocTagNode";
+    })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {}));
+    var NodeFlags;
+    (function (NodeFlags) {
+        NodeFlags[NodeFlags["None"] = 0] = "None";
+        NodeFlags[NodeFlags["Let"] = 1] = "Let";
+        NodeFlags[NodeFlags["Const"] = 2] = "Const";
+        NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace";
+        NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized";
+        NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace";
+        NodeFlags[NodeFlags["ExportContext"] = 32] = "ExportContext";
+        NodeFlags[NodeFlags["ContainsThis"] = 64] = "ContainsThis";
+        NodeFlags[NodeFlags["HasImplicitReturn"] = 128] = "HasImplicitReturn";
+        NodeFlags[NodeFlags["HasExplicitReturn"] = 256] = "HasExplicitReturn";
+        NodeFlags[NodeFlags["GlobalAugmentation"] = 512] = "GlobalAugmentation";
+        NodeFlags[NodeFlags["HasAsyncFunctions"] = 1024] = "HasAsyncFunctions";
+        NodeFlags[NodeFlags["DisallowInContext"] = 2048] = "DisallowInContext";
+        NodeFlags[NodeFlags["YieldContext"] = 4096] = "YieldContext";
+        NodeFlags[NodeFlags["DecoratorContext"] = 8192] = "DecoratorContext";
+        NodeFlags[NodeFlags["AwaitContext"] = 16384] = "AwaitContext";
+        NodeFlags[NodeFlags["ThisNodeHasError"] = 32768] = "ThisNodeHasError";
+        NodeFlags[NodeFlags["JavaScriptFile"] = 65536] = "JavaScriptFile";
+        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 131072] = "ThisNodeOrAnySubNodesHasError";
+        NodeFlags[NodeFlags["HasAggregatedChildData"] = 262144] = "HasAggregatedChildData";
+        // This flag will be set when the parser encounters a dynamic import expression so that module resolution
+        // will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
+        // once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
+        // During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
+        // during module resolution. However, the removal operation should not occur often and in the case of the
+        // removal, it is likely that users will add the import anyway.
+        // The advantage of this approach is its simplicity. For the case of batch compilation,
+        // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
+        /* @internal */
+        NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 524288] = "PossiblyContainsDynamicImport";
+        NodeFlags[NodeFlags["JSDoc"] = 1048576] = "JSDoc";
+        NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped";
+        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 384] = "ReachabilityCheckFlags";
+        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 1408] = "ReachabilityAndEmitFlags";
+        // Parsing context flags
+        NodeFlags[NodeFlags["ContextFlags"] = 96256] = "ContextFlags";
+        // Exclude these flags when parsing a Type
+        NodeFlags[NodeFlags["TypeExcludesFlags"] = 20480] = "TypeExcludesFlags";
+    })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {}));
+    var ModifierFlags;
+    (function (ModifierFlags) {
+        ModifierFlags[ModifierFlags["None"] = 0] = "None";
+        ModifierFlags[ModifierFlags["Export"] = 1] = "Export";
+        ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient";
+        ModifierFlags[ModifierFlags["Public"] = 4] = "Public";
+        ModifierFlags[ModifierFlags["Private"] = 8] = "Private";
+        ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected";
+        ModifierFlags[ModifierFlags["Static"] = 32] = "Static";
+        ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly";
+        ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract";
+        ModifierFlags[ModifierFlags["Async"] = 256] = "Async";
+        ModifierFlags[ModifierFlags["Default"] = 512] = "Default";
+        ModifierFlags[ModifierFlags["Const"] = 2048] = "Const";
+        ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
+        ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
+        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
+        ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
+        ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier";
+        ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier";
+        ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault";
+    })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {}));
+    var JsxFlags;
+    (function (JsxFlags) {
+        JsxFlags[JsxFlags["None"] = 0] = "None";
+        /** An element from a named property of the JSX.IntrinsicElements interface */
+        JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement";
+        /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */
+        JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement";
+        JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement";
+    })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {}));
+    /* @internal */
+    var RelationComparisonResult;
+    (function (RelationComparisonResult) {
+        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
+        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
+        RelationComparisonResult[RelationComparisonResult["FailedAndReported"] = 3] = "FailedAndReported";
+    })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
+    /*@internal*/
+    var GeneratedIdentifierKind;
+    (function (GeneratedIdentifierKind) {
+        GeneratedIdentifierKind[GeneratedIdentifierKind["None"] = 0] = "None";
+        GeneratedIdentifierKind[GeneratedIdentifierKind["Auto"] = 1] = "Auto";
+        GeneratedIdentifierKind[GeneratedIdentifierKind["Loop"] = 2] = "Loop";
+        GeneratedIdentifierKind[GeneratedIdentifierKind["Unique"] = 3] = "Unique";
+        GeneratedIdentifierKind[GeneratedIdentifierKind["Node"] = 4] = "Node";
+    })(GeneratedIdentifierKind = ts.GeneratedIdentifierKind || (ts.GeneratedIdentifierKind = {}));
+    /* @internal */
+    var NumericLiteralFlags;
+    (function (NumericLiteralFlags) {
+        NumericLiteralFlags[NumericLiteralFlags["None"] = 0] = "None";
+        NumericLiteralFlags[NumericLiteralFlags["Scientific"] = 2] = "Scientific";
+        NumericLiteralFlags[NumericLiteralFlags["Octal"] = 4] = "Octal";
+        NumericLiteralFlags[NumericLiteralFlags["HexSpecifier"] = 8] = "HexSpecifier";
+        NumericLiteralFlags[NumericLiteralFlags["BinarySpecifier"] = 16] = "BinarySpecifier";
+        NumericLiteralFlags[NumericLiteralFlags["OctalSpecifier"] = 32] = "OctalSpecifier";
+        NumericLiteralFlags[NumericLiteralFlags["BinaryOrOctalSpecifier"] = 48] = "BinaryOrOctalSpecifier";
+    })(NumericLiteralFlags = ts.NumericLiteralFlags || (ts.NumericLiteralFlags = {}));
+    var FlowFlags;
+    (function (FlowFlags) {
+        FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable";
+        FlowFlags[FlowFlags["Start"] = 2] = "Start";
+        FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel";
+        FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel";
+        FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment";
+        FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition";
+        FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition";
+        FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause";
+        FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation";
+        FlowFlags[FlowFlags["Referenced"] = 512] = "Referenced";
+        FlowFlags[FlowFlags["Shared"] = 1024] = "Shared";
+        FlowFlags[FlowFlags["PreFinally"] = 2048] = "PreFinally";
+        FlowFlags[FlowFlags["AfterFinally"] = 4096] = "AfterFinally";
+        FlowFlags[FlowFlags["Label"] = 12] = "Label";
+        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
+    })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {}));
+    var OperationCanceledException = /** @class */ (function () {
+        function OperationCanceledException() {
+        }
+        return OperationCanceledException;
+    }());
+    ts.OperationCanceledException = OperationCanceledException;
+    /* @internal */
+    var StructureIsReused;
+    (function (StructureIsReused) {
+        StructureIsReused[StructureIsReused["Not"] = 0] = "Not";
+        StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules";
+        StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely";
+    })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {}));
+    /** Return code used by getEmitOutput function to indicate status of the function */
+    var ExitStatus;
+    (function (ExitStatus) {
+        // Compiler ran successfully.  Either this was a simple do-nothing compilation (for example,
+        // when -version or -help was provided, or this was a normal compilation, no diagnostics
+        // were produced, and all outputs were generated successfully.
+        ExitStatus[ExitStatus["Success"] = 0] = "Success";
+        // Diagnostics were produced and because of them no code was generated.
+        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped";
+        // Diagnostics were produced and outputs were generated in spite of them.
+        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated";
+    })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {}));
+    var NodeBuilderFlags;
+    (function (NodeBuilderFlags) {
+        NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None";
+        // Options
+        NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation";
+        NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
+        NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
+        NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
+        NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
+        NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName";
+        // Error handling
+        NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 1024] = "AllowThisInObjectLiteral";
+        NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 2048] = "AllowQualifedNameInPlaceOfIdentifier";
+        NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 8192] = "AllowAnonymousIdentifier";
+        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 16384] = "AllowEmptyUnionOrIntersection";
+        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 32768] = "AllowEmptyTuple";
+        NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 60416] = "IgnoreErrors";
+        // State
+        NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 1048576] = "InObjectTypeLiteral";
+        NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
+    })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {}));
+    var TypeFormatFlags;
+    (function (TypeFormatFlags) {
+        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
+        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 1] = "WriteArrayAsGenericType";
+        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4] = "UseTypeOfFunction";
+        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 8] = "NoTruncation";
+        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 16] = "WriteArrowStyleSignature";
+        TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 32] = "WriteOwnNameForAnyLike";
+        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 64] = "WriteTypeArgumentsOfSignature";
+        TypeFormatFlags[TypeFormatFlags["InElementType"] = 128] = "InElementType";
+        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 256] = "UseFullyQualifiedType";
+        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 512] = "InFirstTypeArgument";
+        TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 1024] = "InTypeAlias";
+        TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 4096] = "SuppressAnyReturnType";
+        TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined";
+        TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral";
+        TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType";
+        TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope";
+        // even though `T` can't be accessed in the current scope.
+    })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
+    var SymbolFormatFlags;
+    (function (SymbolFormatFlags) {
+        SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
+        // Write symbols's type argument if it is instantiated symbol
+        // eg. class C<T> { p: T }   <-- Show p as C<T>.p here
+        //     var a: C<number>;
+        //     var p = a.p;  <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
+        SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
+        // Use only external alias information to get the symbol name in the given context
+        // eg.  module m { export class c { } } import x = m.c;
+        // When this flag is specified m.c will be used to refer to the class instead of alias symbol x
+        SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
+    })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
+    /* @internal */
+    var SymbolAccessibility;
+    (function (SymbolAccessibility) {
+        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
+        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
+        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
+    })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
+    /* @internal */
+    var SyntheticSymbolKind;
+    (function (SyntheticSymbolKind) {
+        SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection";
+        SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread";
+    })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {}));
+    var TypePredicateKind;
+    (function (TypePredicateKind) {
+        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
+        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
+    })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {}));
+    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
+    /* @internal */
+    var TypeReferenceSerializationKind;
+    (function (TypeReferenceSerializationKind) {
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown";
+        // should be emitted using a safe fallback.
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue";
+        // function that can be reached at runtime (e.g. a `class`
+        // declaration or a `var` declaration for the static side
+        // of a type, such as the global `Promise` type in lib.d.ts).
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 4] = "StringLikeType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 5] = "BooleanType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 6] = "ArrayLikeType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 7] = "ESSymbolType";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 8] = "Promise";
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 9] = "TypeWithCallSignature";
+        // with call signatures.
+        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 10] = "ObjectType";
+    })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
+    var SymbolFlags;
+    (function (SymbolFlags) {
+        SymbolFlags[SymbolFlags["None"] = 0] = "None";
+        SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
+        SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
+        SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
+        SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
+        SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
+        SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
+        SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
+        SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
+        SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
+        SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
+        SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
+        SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
+        SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
+        SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
+        SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
+        SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
+        SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
+        SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature";
+        SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter";
+        SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias";
+        SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue";
+        SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias";
+        SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype";
+        SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar";
+        SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional";
+        SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient";
+        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
+        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
+        SymbolFlags[SymbolFlags["Value"] = 107455] = "Value";
+        SymbolFlags[SymbolFlags["Type"] = 793064] = "Type";
+        SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace";
+        SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
+        SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
+        // Variables can be redeclared, but can not redeclare a block-scoped declaration with the
+        // same name, or any other value that is not a variable, e.g. ValueModule or Class
+        SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 107454] = "FunctionScopedVariableExcludes";
+        // Block-scoped declarations are not allowed to be re-declared
+        // they can not merge with anything in the value space
+        SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes";
+        SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes";
+        SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes";
+        SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 900095] = "EnumMemberExcludes";
+        SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes";
+        SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes";
+        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 792968] = "InterfaceExcludes";
+        SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 899327] = "RegularEnumExcludes";
+        SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 899967] = "ConstEnumExcludes";
+        SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 106639] = "ValueModuleExcludes";
+        SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
+        SymbolFlags[SymbolFlags["MethodExcludes"] = 99263] = "MethodExcludes";
+        SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 41919] = "GetAccessorExcludes";
+        SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 74687] = "SetAccessorExcludes";
+        SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 530920] = "TypeParameterExcludes";
+        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 793064] = "TypeAliasExcludes";
+        SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes";
+        SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember";
+        SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
+        SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports";
+        SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers";
+        SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped";
+        SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
+        SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember";
+        /* @internal */
+        // The set of things we consider semantically classifiable.  Used to speed up the LS during
+        // classification.
+        SymbolFlags[SymbolFlags["Classifiable"] = 788448] = "Classifiable";
+    })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {}));
+    /* @internal */
+    var EnumKind;
+    (function (EnumKind) {
+        EnumKind[EnumKind["Numeric"] = 0] = "Numeric";
+        EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type)
+    })(EnumKind = ts.EnumKind || (ts.EnumKind = {}));
+    /* @internal */
+    var CheckFlags;
+    (function (CheckFlags) {
+        CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated";
+        CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty";
+        CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod";
+        CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly";
+        CheckFlags[CheckFlags["Partial"] = 16] = "Partial";
+        CheckFlags[CheckFlags["HasNonUniformType"] = 32] = "HasNonUniformType";
+        CheckFlags[CheckFlags["ContainsPublic"] = 64] = "ContainsPublic";
+        CheckFlags[CheckFlags["ContainsProtected"] = 128] = "ContainsProtected";
+        CheckFlags[CheckFlags["ContainsPrivate"] = 256] = "ContainsPrivate";
+        CheckFlags[CheckFlags["ContainsStatic"] = 512] = "ContainsStatic";
+        CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
+    })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {}));
+    var InternalSymbolName;
+    (function (InternalSymbolName) {
+        InternalSymbolName["Call"] = "__call";
+        InternalSymbolName["Constructor"] = "__constructor";
+        InternalSymbolName["New"] = "__new";
+        InternalSymbolName["Index"] = "__index";
+        InternalSymbolName["ExportStar"] = "__export";
+        InternalSymbolName["Global"] = "__global";
+        InternalSymbolName["Missing"] = "__missing";
+        InternalSymbolName["Type"] = "__type";
+        InternalSymbolName["Object"] = "__object";
+        InternalSymbolName["JSXAttributes"] = "__jsxAttributes";
+        InternalSymbolName["Class"] = "__class";
+        InternalSymbolName["Function"] = "__function";
+        InternalSymbolName["Computed"] = "__computed";
+        InternalSymbolName["Resolving"] = "__resolving__";
+        InternalSymbolName["ExportEquals"] = "export=";
+        InternalSymbolName["Default"] = "default";
+    })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {}));
+    /* @internal */
+    var NodeCheckFlags;
+    (function (NodeCheckFlags) {
+        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
+        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
+        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
+        NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget";
+        NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance";
+        NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic";
+        NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked";
+        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper";
+        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding";
+        NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments";
+        NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed";
+        NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass";
+        NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding";
+        NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 131072] = "CapturedBlockScopedBinding";
+        NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 262144] = "BlockScopedBindingInLoop";
+        NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 524288] = "ClassWithBodyScopedClassBinding";
+        NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 1048576] = "BodyScopedClassBinding";
+        NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 2097152] = "NeedsLoopOutParameter";
+        NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 4194304] = "AssignmentsMarked";
+        NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 8388608] = "ClassWithConstructorReference";
+        NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 16777216] = "ConstructorReferenceInClass";
+    })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
+    var TypeFlags;
+    (function (TypeFlags) {
+        TypeFlags[TypeFlags["Any"] = 1] = "Any";
+        TypeFlags[TypeFlags["String"] = 2] = "String";
+        TypeFlags[TypeFlags["Number"] = 4] = "Number";
+        TypeFlags[TypeFlags["Boolean"] = 8] = "Boolean";
+        TypeFlags[TypeFlags["Enum"] = 16] = "Enum";
+        TypeFlags[TypeFlags["StringLiteral"] = 32] = "StringLiteral";
+        TypeFlags[TypeFlags["NumberLiteral"] = 64] = "NumberLiteral";
+        TypeFlags[TypeFlags["BooleanLiteral"] = 128] = "BooleanLiteral";
+        TypeFlags[TypeFlags["EnumLiteral"] = 256] = "EnumLiteral";
+        TypeFlags[TypeFlags["ESSymbol"] = 512] = "ESSymbol";
+        TypeFlags[TypeFlags["Void"] = 1024] = "Void";
+        TypeFlags[TypeFlags["Undefined"] = 2048] = "Undefined";
+        TypeFlags[TypeFlags["Null"] = 4096] = "Null";
+        TypeFlags[TypeFlags["Never"] = 8192] = "Never";
+        TypeFlags[TypeFlags["TypeParameter"] = 16384] = "TypeParameter";
+        TypeFlags[TypeFlags["Object"] = 32768] = "Object";
+        TypeFlags[TypeFlags["Union"] = 65536] = "Union";
+        TypeFlags[TypeFlags["Intersection"] = 131072] = "Intersection";
+        TypeFlags[TypeFlags["Index"] = 262144] = "Index";
+        TypeFlags[TypeFlags["IndexedAccess"] = 524288] = "IndexedAccess";
+        /* @internal */
+        TypeFlags[TypeFlags["FreshLiteral"] = 1048576] = "FreshLiteral";
+        /* @internal */
+        TypeFlags[TypeFlags["ContainsWideningType"] = 2097152] = "ContainsWideningType";
+        /* @internal */
+        TypeFlags[TypeFlags["ContainsObjectLiteral"] = 4194304] = "ContainsObjectLiteral";
+        /* @internal */
+        TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 8388608] = "ContainsAnyFunctionType";
+        TypeFlags[TypeFlags["NonPrimitive"] = 16777216] = "NonPrimitive";
+        /* @internal */
+        TypeFlags[TypeFlags["JsxAttributes"] = 33554432] = "JsxAttributes";
+        TypeFlags[TypeFlags["MarkerType"] = 67108864] = "MarkerType";
+        /* @internal */
+        TypeFlags[TypeFlags["Nullable"] = 6144] = "Nullable";
+        TypeFlags[TypeFlags["Literal"] = 224] = "Literal";
+        TypeFlags[TypeFlags["Unit"] = 6368] = "Unit";
+        TypeFlags[TypeFlags["StringOrNumberLiteral"] = 96] = "StringOrNumberLiteral";
+        /* @internal */
+        TypeFlags[TypeFlags["DefinitelyFalsy"] = 7392] = "DefinitelyFalsy";
+        TypeFlags[TypeFlags["PossiblyFalsy"] = 7406] = "PossiblyFalsy";
+        /* @internal */
+        TypeFlags[TypeFlags["Intrinsic"] = 16793231] = "Intrinsic";
+        /* @internal */
+        TypeFlags[TypeFlags["Primitive"] = 8190] = "Primitive";
+        TypeFlags[TypeFlags["StringLike"] = 262178] = "StringLike";
+        TypeFlags[TypeFlags["NumberLike"] = 84] = "NumberLike";
+        TypeFlags[TypeFlags["BooleanLike"] = 136] = "BooleanLike";
+        TypeFlags[TypeFlags["EnumLike"] = 272] = "EnumLike";
+        TypeFlags[TypeFlags["UnionOrIntersection"] = 196608] = "UnionOrIntersection";
+        TypeFlags[TypeFlags["StructuredType"] = 229376] = "StructuredType";
+        TypeFlags[TypeFlags["StructuredOrTypeVariable"] = 1032192] = "StructuredOrTypeVariable";
+        TypeFlags[TypeFlags["TypeVariable"] = 540672] = "TypeVariable";
+        // 'Narrowable' types are types where narrowing actually narrows.
+        // This *should* be every type other than null, undefined, void, and never
+        TypeFlags[TypeFlags["Narrowable"] = 17810175] = "Narrowable";
+        TypeFlags[TypeFlags["NotUnionOrUnit"] = 16810497] = "NotUnionOrUnit";
+        /* @internal */
+        TypeFlags[TypeFlags["RequiresWidening"] = 6291456] = "RequiresWidening";
+        /* @internal */
+        TypeFlags[TypeFlags["PropagatingFlags"] = 14680064] = "PropagatingFlags";
+    })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {}));
+    var ObjectFlags;
+    (function (ObjectFlags) {
+        ObjectFlags[ObjectFlags["Class"] = 1] = "Class";
+        ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface";
+        ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference";
+        ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple";
+        ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous";
+        ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped";
+        ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated";
+        ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral";
+        ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray";
+        ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties";
+        ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface";
+    })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {}));
+    /* @internal */
+    var Variance;
+    (function (Variance) {
+        Variance[Variance["Invariant"] = 0] = "Invariant";
+        Variance[Variance["Covariant"] = 1] = "Covariant";
+        Variance[Variance["Contravariant"] = 2] = "Contravariant";
+        Variance[Variance["Bivariant"] = 3] = "Bivariant";
+        Variance[Variance["Independent"] = 4] = "Independent";
+    })(Variance = ts.Variance || (ts.Variance = {}));
+    var SignatureKind;
+    (function (SignatureKind) {
+        SignatureKind[SignatureKind["Call"] = 0] = "Call";
+        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
+    })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {}));
+    var IndexKind;
+    (function (IndexKind) {
+        IndexKind[IndexKind["String"] = 0] = "String";
+        IndexKind[IndexKind["Number"] = 1] = "Number";
+    })(IndexKind = ts.IndexKind || (ts.IndexKind = {}));
+    var InferencePriority;
+    (function (InferencePriority) {
+        InferencePriority[InferencePriority["Contravariant"] = 1] = "Contravariant";
+        InferencePriority[InferencePriority["NakedTypeVariable"] = 2] = "NakedTypeVariable";
+        InferencePriority[InferencePriority["MappedType"] = 4] = "MappedType";
+        InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType";
+    })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {}));
+    var InferenceFlags;
+    (function (InferenceFlags) {
+        InferenceFlags[InferenceFlags["InferUnionTypes"] = 1] = "InferUnionTypes";
+        InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault";
+        InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault";
+    })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {}));
+    /**
+     * Ternary values are defined such that
+     * x & y is False if either x or y is False.
+     * x & y is Maybe if either x or y is Maybe, but neither x or y is False.
+     * x & y is True if both x and y are True.
+     * x | y is False if both x and y are False.
+     * x | y is Maybe if either x or y is Maybe, but neither x or y is True.
+     * x | y is True if either x or y is True.
+     */
+    var Ternary;
+    (function (Ternary) {
+        Ternary[Ternary["False"] = 0] = "False";
+        Ternary[Ternary["Maybe"] = 1] = "Maybe";
+        Ternary[Ternary["True"] = -1] = "True";
+    })(Ternary = ts.Ternary || (ts.Ternary = {}));
+    /* @internal */
+    var SpecialPropertyAssignmentKind;
+    (function (SpecialPropertyAssignmentKind) {
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["None"] = 0] = "None";
+        /// exports.name = expr
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ExportsProperty"] = 1] = "ExportsProperty";
+        /// module.exports = expr
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ModuleExports"] = 2] = "ModuleExports";
+        /// className.prototype.name = expr
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["PrototypeProperty"] = 3] = "PrototypeProperty";
+        /// this.name = expr
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ThisProperty"] = 4] = "ThisProperty";
+        // F.name = expr
+        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["Property"] = 5] = "Property";
+    })(SpecialPropertyAssignmentKind = ts.SpecialPropertyAssignmentKind || (ts.SpecialPropertyAssignmentKind = {}));
+    var DiagnosticCategory;
+    (function (DiagnosticCategory) {
+        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
+        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
+        DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message";
+    })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
+    var ModuleResolutionKind;
+    (function (ModuleResolutionKind) {
+        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
+        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
+    })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
+    var ModuleKind;
+    (function (ModuleKind) {
+        ModuleKind[ModuleKind["None"] = 0] = "None";
+        ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
+        ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
+        ModuleKind[ModuleKind["UMD"] = 3] = "UMD";
+        ModuleKind[ModuleKind["System"] = 4] = "System";
+        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
+        ModuleKind[ModuleKind["ESNext"] = 6] = "ESNext";
+    })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {}));
+    var JsxEmit;
+    (function (JsxEmit) {
+        JsxEmit[JsxEmit["None"] = 0] = "None";
+        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
+        JsxEmit[JsxEmit["React"] = 2] = "React";
+        JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative";
+    })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {}));
+    var NewLineKind;
+    (function (NewLineKind) {
+        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
+        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
+    })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {}));
+    var ScriptKind;
+    (function (ScriptKind) {
+        ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown";
+        ScriptKind[ScriptKind["JS"] = 1] = "JS";
+        ScriptKind[ScriptKind["JSX"] = 2] = "JSX";
+        ScriptKind[ScriptKind["TS"] = 3] = "TS";
+        ScriptKind[ScriptKind["TSX"] = 4] = "TSX";
+        ScriptKind[ScriptKind["External"] = 5] = "External";
+        ScriptKind[ScriptKind["JSON"] = 6] = "JSON";
+    })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {}));
+    var ScriptTarget;
+    (function (ScriptTarget) {
+        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
+        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
+        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
+        ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016";
+        ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017";
+        ScriptTarget[ScriptTarget["ESNext"] = 5] = "ESNext";
+        ScriptTarget[ScriptTarget["Latest"] = 5] = "Latest";
+    })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {}));
+    var LanguageVariant;
+    (function (LanguageVariant) {
+        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
+        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
+    })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {}));
+    /* @internal */
+    var DiagnosticStyle;
+    (function (DiagnosticStyle) {
+        DiagnosticStyle[DiagnosticStyle["Simple"] = 0] = "Simple";
+        DiagnosticStyle[DiagnosticStyle["Pretty"] = 1] = "Pretty";
+    })(DiagnosticStyle = ts.DiagnosticStyle || (ts.DiagnosticStyle = {}));
+    var WatchDirectoryFlags;
+    (function (WatchDirectoryFlags) {
+        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
+        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
+    })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
+    /* @internal */
+    var CharacterCodes;
+    (function (CharacterCodes) {
+        CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
+        CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
+        CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
+        CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
+        CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
+        CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
+        CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
+        // Unicode 3.0 space characters
+        CharacterCodes[CharacterCodes["space"] = 32] = "space";
+        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
+        CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
+        CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
+        CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
+        CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
+        CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
+        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
+        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
+        CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
+        CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
+        CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
+        CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
+        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
+        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
+        CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
+        CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
+        CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
+        CharacterCodes[CharacterCodes["_"] = 95] = "_";
+        CharacterCodes[CharacterCodes["$"] = 36] = "$";
+        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
+        CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
+        CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
+        CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
+        CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
+        CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
+        CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
+        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
+        CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
+        CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
+        CharacterCodes[CharacterCodes["a"] = 97] = "a";
+        CharacterCodes[CharacterCodes["b"] = 98] = "b";
+        CharacterCodes[CharacterCodes["c"] = 99] = "c";
+        CharacterCodes[CharacterCodes["d"] = 100] = "d";
+        CharacterCodes[CharacterCodes["e"] = 101] = "e";
+        CharacterCodes[CharacterCodes["f"] = 102] = "f";
+        CharacterCodes[CharacterCodes["g"] = 103] = "g";
+        CharacterCodes[CharacterCodes["h"] = 104] = "h";
+        CharacterCodes[CharacterCodes["i"] = 105] = "i";
+        CharacterCodes[CharacterCodes["j"] = 106] = "j";
+        CharacterCodes[CharacterCodes["k"] = 107] = "k";
+        CharacterCodes[CharacterCodes["l"] = 108] = "l";
+        CharacterCodes[CharacterCodes["m"] = 109] = "m";
+        CharacterCodes[CharacterCodes["n"] = 110] = "n";
+        CharacterCodes[CharacterCodes["o"] = 111] = "o";
+        CharacterCodes[CharacterCodes["p"] = 112] = "p";
+        CharacterCodes[CharacterCodes["q"] = 113] = "q";
+        CharacterCodes[CharacterCodes["r"] = 114] = "r";
+        CharacterCodes[CharacterCodes["s"] = 115] = "s";
+        CharacterCodes[CharacterCodes["t"] = 116] = "t";
+        CharacterCodes[CharacterCodes["u"] = 117] = "u";
+        CharacterCodes[CharacterCodes["v"] = 118] = "v";
+        CharacterCodes[CharacterCodes["w"] = 119] = "w";
+        CharacterCodes[CharacterCodes["x"] = 120] = "x";
+        CharacterCodes[CharacterCodes["y"] = 121] = "y";
+        CharacterCodes[CharacterCodes["z"] = 122] = "z";
+        CharacterCodes[CharacterCodes["A"] = 65] = "A";
+        CharacterCodes[CharacterCodes["B"] = 66] = "B";
+        CharacterCodes[CharacterCodes["C"] = 67] = "C";
+        CharacterCodes[CharacterCodes["D"] = 68] = "D";
+        CharacterCodes[CharacterCodes["E"] = 69] = "E";
+        CharacterCodes[CharacterCodes["F"] = 70] = "F";
+        CharacterCodes[CharacterCodes["G"] = 71] = "G";
+        CharacterCodes[CharacterCodes["H"] = 72] = "H";
+        CharacterCodes[CharacterCodes["I"] = 73] = "I";
+        CharacterCodes[CharacterCodes["J"] = 74] = "J";
+        CharacterCodes[CharacterCodes["K"] = 75] = "K";
+        CharacterCodes[CharacterCodes["L"] = 76] = "L";
+        CharacterCodes[CharacterCodes["M"] = 77] = "M";
+        CharacterCodes[CharacterCodes["N"] = 78] = "N";
+        CharacterCodes[CharacterCodes["O"] = 79] = "O";
+        CharacterCodes[CharacterCodes["P"] = 80] = "P";
+        CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
+        CharacterCodes[CharacterCodes["R"] = 82] = "R";
+        CharacterCodes[CharacterCodes["S"] = 83] = "S";
+        CharacterCodes[CharacterCodes["T"] = 84] = "T";
+        CharacterCodes[CharacterCodes["U"] = 85] = "U";
+        CharacterCodes[CharacterCodes["V"] = 86] = "V";
+        CharacterCodes[CharacterCodes["W"] = 87] = "W";
+        CharacterCodes[CharacterCodes["X"] = 88] = "X";
+        CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
+        CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
+        CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
+        CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
+        CharacterCodes[CharacterCodes["at"] = 64] = "at";
+        CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
+        CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
+        CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
+        CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
+        CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
+        CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
+        CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
+        CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
+        CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
+        CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
+        CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
+        CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
+        CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
+        CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
+        CharacterCodes[CharacterCodes["hash"] = 35] = "hash";
+        CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
+        CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
+        CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
+        CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
+        CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
+        CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
+        CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
+        CharacterCodes[CharacterCodes["question"] = 63] = "question";
+        CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
+        CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
+        CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
+        CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
+        CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
+        CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
+        CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
+        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
+        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
+    })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {}));
+    var Extension;
+    (function (Extension) {
+        Extension["Ts"] = ".ts";
+        Extension["Tsx"] = ".tsx";
+        Extension["Dts"] = ".d.ts";
+        Extension["Js"] = ".js";
+        Extension["Jsx"] = ".jsx";
+        Extension["Json"] = ".json";
+    })(Extension = ts.Extension || (ts.Extension = {}));
+    /* @internal */
+    var TransformFlags;
+    (function (TransformFlags) {
+        TransformFlags[TransformFlags["None"] = 0] = "None";
+        // Facts
+        // - Flags used to indicate that a node or subtree contains syntax that requires transformation.
+        TransformFlags[TransformFlags["TypeScript"] = 1] = "TypeScript";
+        TransformFlags[TransformFlags["ContainsTypeScript"] = 2] = "ContainsTypeScript";
+        TransformFlags[TransformFlags["ContainsJsx"] = 4] = "ContainsJsx";
+        TransformFlags[TransformFlags["ContainsESNext"] = 8] = "ContainsESNext";
+        TransformFlags[TransformFlags["ContainsES2017"] = 16] = "ContainsES2017";
+        TransformFlags[TransformFlags["ContainsES2016"] = 32] = "ContainsES2016";
+        TransformFlags[TransformFlags["ES2015"] = 64] = "ES2015";
+        TransformFlags[TransformFlags["ContainsES2015"] = 128] = "ContainsES2015";
+        TransformFlags[TransformFlags["Generator"] = 256] = "Generator";
+        TransformFlags[TransformFlags["ContainsGenerator"] = 512] = "ContainsGenerator";
+        TransformFlags[TransformFlags["DestructuringAssignment"] = 1024] = "DestructuringAssignment";
+        TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 2048] = "ContainsDestructuringAssignment";
+        // Markers
+        // - Flags used to indicate that a subtree contains a specific transformation.
+        TransformFlags[TransformFlags["ContainsDecorators"] = 4096] = "ContainsDecorators";
+        TransformFlags[TransformFlags["ContainsPropertyInitializer"] = 8192] = "ContainsPropertyInitializer";
+        TransformFlags[TransformFlags["ContainsLexicalThis"] = 16384] = "ContainsLexicalThis";
+        TransformFlags[TransformFlags["ContainsCapturedLexicalThis"] = 32768] = "ContainsCapturedLexicalThis";
+        TransformFlags[TransformFlags["ContainsLexicalThisInComputedPropertyName"] = 65536] = "ContainsLexicalThisInComputedPropertyName";
+        TransformFlags[TransformFlags["ContainsDefaultValueAssignments"] = 131072] = "ContainsDefaultValueAssignments";
+        TransformFlags[TransformFlags["ContainsParameterPropertyAssignments"] = 262144] = "ContainsParameterPropertyAssignments";
+        TransformFlags[TransformFlags["ContainsSpread"] = 524288] = "ContainsSpread";
+        TransformFlags[TransformFlags["ContainsObjectSpread"] = 1048576] = "ContainsObjectSpread";
+        TransformFlags[TransformFlags["ContainsRest"] = 524288] = "ContainsRest";
+        TransformFlags[TransformFlags["ContainsObjectRest"] = 1048576] = "ContainsObjectRest";
+        TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 2097152] = "ContainsComputedPropertyName";
+        TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 4194304] = "ContainsBlockScopedBinding";
+        TransformFlags[TransformFlags["ContainsBindingPattern"] = 8388608] = "ContainsBindingPattern";
+        TransformFlags[TransformFlags["ContainsYield"] = 16777216] = "ContainsYield";
+        TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 33554432] = "ContainsHoistedDeclarationOrCompletion";
+        TransformFlags[TransformFlags["ContainsDynamicImport"] = 67108864] = "ContainsDynamicImport";
+        // Please leave this as 1 << 29.
+        // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
+        // It is a good reminder of how much room we have left
+        TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
+        // Assertions
+        // - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
+        TransformFlags[TransformFlags["AssertTypeScript"] = 3] = "AssertTypeScript";
+        TransformFlags[TransformFlags["AssertJsx"] = 4] = "AssertJsx";
+        TransformFlags[TransformFlags["AssertESNext"] = 8] = "AssertESNext";
+        TransformFlags[TransformFlags["AssertES2017"] = 16] = "AssertES2017";
+        TransformFlags[TransformFlags["AssertES2016"] = 32] = "AssertES2016";
+        TransformFlags[TransformFlags["AssertES2015"] = 192] = "AssertES2015";
+        TransformFlags[TransformFlags["AssertGenerator"] = 768] = "AssertGenerator";
+        TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 3072] = "AssertDestructuringAssignment";
+        // Scope Exclusions
+        // - Bitmasks that exclude flags from propagating out of a specific context
+        //   into the subtree flags of their container.
+        TransformFlags[TransformFlags["NodeExcludes"] = 536872257] = "NodeExcludes";
+        TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 601249089] = "ArrowFunctionExcludes";
+        TransformFlags[TransformFlags["FunctionExcludes"] = 601281857] = "FunctionExcludes";
+        TransformFlags[TransformFlags["ConstructorExcludes"] = 601015617] = "ConstructorExcludes";
+        TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 601015617] = "MethodOrAccessorExcludes";
+        TransformFlags[TransformFlags["ClassExcludes"] = 539358529] = "ClassExcludes";
+        TransformFlags[TransformFlags["ModuleExcludes"] = 574674241] = "ModuleExcludes";
+        TransformFlags[TransformFlags["TypeExcludes"] = -3] = "TypeExcludes";
+        TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 540087617] = "ObjectLiteralExcludes";
+        TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 537396545] = "ArrayLiteralOrCallOrNewExcludes";
+        TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 546309441] = "VariableDeclarationListExcludes";
+        TransformFlags[TransformFlags["ParameterExcludes"] = 536872257] = "ParameterExcludes";
+        TransformFlags[TransformFlags["CatchClauseExcludes"] = 537920833] = "CatchClauseExcludes";
+        TransformFlags[TransformFlags["BindingPatternExcludes"] = 537396545] = "BindingPatternExcludes";
+        // Masks
+        // - Additional bitmasks
+        TransformFlags[TransformFlags["TypeScriptClassSyntaxMask"] = 274432] = "TypeScriptClassSyntaxMask";
+        TransformFlags[TransformFlags["ES2015FunctionSyntaxMask"] = 163840] = "ES2015FunctionSyntaxMask";
+    })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {}));
+    var EmitFlags;
+    (function (EmitFlags) {
+        EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine";
+        EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode";
+        EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution";
+        EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis";
+        EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap";
+        EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap";
+        EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap";
+        EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps";
+        EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps";
+        EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps";
+        EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps";
+        EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments";
+        EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments";
+        EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments";
+        EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments";
+        EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName";
+        EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName";
+        EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName";
+        EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName";
+        EmitFlags[EmitFlags["Indented"] = 65536] = "Indented";
+        EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation";
+        EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody";
+        EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope";
+        EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue";
+        EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting";
+        EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
+        EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
+        EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
+        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
+    })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
+    /**
+     * Used by the checker, this enum keeps track of external emit helpers that should be type
+     * checked.
+     */
+    /* @internal */
+    var ExternalEmitHelpers;
+    (function (ExternalEmitHelpers) {
+        ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends";
+        ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign";
+        ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest";
+        ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate";
+        ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata";
+        ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param";
+        ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter";
+        ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator";
+        ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values";
+        ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read";
+        ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread";
+        ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 2048] = "Await";
+        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 4096] = "AsyncGenerator";
+        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 8192] = "AsyncDelegator";
+        ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 16384] = "AsyncValues";
+        ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 32768] = "ExportStar";
+        ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 65536] = "MakeTemplateObject";
+        ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper";
+        ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 65536] = "LastEmitHelper";
+        // Helpers included by ES2015 for..of
+        ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes";
+        // Helpers included by ES2017 for..await..of
+        ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 16384] = "ForAwaitOfIncludes";
+        // Helpers included by ES2017 async generators
+        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 6144] = "AsyncGeneratorIncludes";
+        // Helpers included by yield* in ES2017 async generators
+        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 26624] = "AsyncDelegatorIncludes";
+        // Helpers included by ES2015 spread
+        ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes";
+    })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {}));
+    var EmitHint;
+    (function (EmitHint) {
+        EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile";
+        EmitHint[EmitHint["Expression"] = 1] = "Expression";
+        EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName";
+        EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter";
+        EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified";
+    })(EmitHint = ts.EmitHint || (ts.EmitHint = {}));
+})(ts || (ts = {}));
+/*@internal*/
+var ts;
+(function (ts) {
+    /** Gets a timestamp with (at least) ms resolution */
+    ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); };
+})(ts || (ts = {}));
+/*@internal*/
+/** Performance measurements for the compiler. */
+(function (ts) {
+    var performance;
+    (function (performance) {
+        var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
+            ? onProfilerEvent
+            : function (_markName) { };
+        var enabled = false;
+        var profilerStart = 0;
+        var counts;
+        var marks;
+        var measures;
+        /**
+         * Marks a performance event.
+         *
+         * @param markName The name of the mark.
+         */
+        function mark(markName) {
+            if (enabled) {
+                marks.set(markName, ts.timestamp());
+                counts.set(markName, (counts.get(markName) || 0) + 1);
+                profilerEvent(markName);
+            }
+        }
+        performance.mark = mark;
+        /**
+         * Adds a performance measurement with the specified name.
+         *
+         * @param measureName The name of the performance measurement.
+         * @param startMarkName The name of the starting mark. If not supplied, the point at which the
+         *      profiler was enabled is used.
+         * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
+         *      used.
+         */
+        function measure(measureName, startMarkName, endMarkName) {
+            if (enabled) {
+                var end = endMarkName && marks.get(endMarkName) || ts.timestamp();
+                var start = startMarkName && marks.get(startMarkName) || profilerStart;
+                measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
+            }
+        }
+        performance.measure = measure;
+        /**
+         * Gets the number of times a marker was encountered.
+         *
+         * @param markName The name of the mark.
+         */
+        function getCount(markName) {
+            return counts && counts.get(markName) || 0;
+        }
+        performance.getCount = getCount;
+        /**
+         * Gets the total duration of all measurements with the supplied name.
+         *
+         * @param measureName The name of the measure whose durations should be accumulated.
+         */
+        function getDuration(measureName) {
+            return measures && measures.get(measureName) || 0;
+        }
+        performance.getDuration = getDuration;
+        /**
+         * Iterate over each measure, performing some action
+         *
+         * @param cb The action to perform for each measure
+         */
+        function forEachMeasure(cb) {
+            measures.forEach(function (measure, key) {
+                cb(key, measure);
+            });
+        }
+        performance.forEachMeasure = forEachMeasure;
+        /** Enables (and resets) performance measurements for the compiler. */
+        function enable() {
+            counts = ts.createMap();
+            marks = ts.createMap();
+            measures = ts.createMap();
+            enabled = true;
+            profilerStart = ts.timestamp();
+        }
+        performance.enable = enable;
+        /** Disables performance measurements for the compiler. */
+        function disable() {
+            enabled = false;
+        }
+        performance.disable = disable;
+    })(performance = ts.performance || (ts.performance = {}));
+})(ts || (ts = {}));
+/// <reference path="types.ts"/>
+/// <reference path="performance.ts" />
+var ts;
+(function (ts) {
+    // WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
+    // If changing the text in this section, be sure to test `configureNightly` too.
+    ts.versionMajorMinor = "2.6";
+    /** The version of the TypeScript compiler release */
+    ts.version = ts.versionMajorMinor + ".1";
+})(ts || (ts = {}));
+(function (ts) {
+    function isExternalModuleNameRelative(moduleName) {
+        // TypeScript 1.0 spec (April 2014): 11.2.1
+        // An external module name is "relative" if the first term is "." or "..".
+        // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
+        return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName);
+    }
+    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
+})(ts || (ts = {}));
+/* @internal */
+(function (ts) {
+    // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
+    ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
+    // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
+    ts.localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
+    /** Create a MapLike with good performance. */
+    function createDictionaryObject() {
+        var map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword
+        // Using 'delete' on an object causes V8 to put the object in dictionary mode.
+        // This disables creation of hidden classes, which are expensive when an object is
+        // constantly changing shape.
+        map.__ = undefined;
+        delete map.__;
+        return map;
+    }
+    /** Create a new map. If a template object is provided, the map will copy entries from it. */
+    function createMap() {
+        return new MapCtr();
+    }
+    ts.createMap = createMap;
+    /** Create a new escaped identifier map. */
+    function createUnderscoreEscapedMap() {
+        return new MapCtr();
+    }
+    ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap;
+    function createSymbolTable(symbols) {
+        var result = createMap();
+        if (symbols) {
+            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
+                var symbol = symbols_1[_i];
+                result.set(symbol.escapedName, symbol);
+            }
+        }
+        return result;
+    }
+    ts.createSymbolTable = createSymbolTable;
+    function createMapFromTemplate(template) {
+        var map = new MapCtr();
+        // Copies keys/values from template. Note that for..in will not throw if
+        // template is undefined, and instead will just exit the loop.
+        for (var key in template) {
+            if (hasOwnProperty.call(template, key)) {
+                map.set(key, template[key]);
+            }
+        }
+        return map;
+    }
+    ts.createMapFromTemplate = createMapFromTemplate;
+    // Internet Explorer's Map doesn't support iteration, so don't use it.
+    // tslint:disable-next-line:no-in-operator
+    var MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
+    // Keep the class inside a function so it doesn't get compiled if it's not used.
+    function shimMap() {
+        var MapIterator = /** @class */ (function () {
+            function MapIterator(data, selector) {
+                this.index = 0;
+                this.data = data;
+                this.selector = selector;
+                this.keys = Object.keys(data);
+            }
+            MapIterator.prototype.next = function () {
+                var index = this.index;
+                if (index < this.keys.length) {
+                    this.index++;
+                    return { value: this.selector(this.data, this.keys[index]), done: false };
+                }
+                return { value: undefined, done: true };
+            };
+            return MapIterator;
+        }());
+        return /** @class */ (function () {
+            function class_1() {
+                this.data = createDictionaryObject();
+                this.size = 0;
+            }
+            class_1.prototype.get = function (key) {
+                return this.data[key];
+            };
+            class_1.prototype.set = function (key, value) {
+                if (!this.has(key)) {
+                    this.size++;
+                }
+                this.data[key] = value;
+                return this;
+            };
+            class_1.prototype.has = function (key) {
+                // tslint:disable-next-line:no-in-operator
+                return key in this.data;
+            };
+            class_1.prototype.delete = function (key) {
+                if (this.has(key)) {
+                    this.size--;
+                    delete this.data[key];
+                    return true;
+                }
+                return false;
+            };
+            class_1.prototype.clear = function () {
+                this.data = createDictionaryObject();
+                this.size = 0;
+            };
+            class_1.prototype.keys = function () {
+                return new MapIterator(this.data, function (_data, key) { return key; });
+            };
+            class_1.prototype.values = function () {
+                return new MapIterator(this.data, function (data, key) { return data[key]; });
+            };
+            class_1.prototype.entries = function () {
+                return new MapIterator(this.data, function (data, key) { return [key, data[key]]; });
+            };
+            class_1.prototype.forEach = function (action) {
+                for (var key in this.data) {
+                    action(this.data[key], key);
+                }
+            };
+            return class_1;
+        }());
+    }
+    function toPath(fileName, basePath, getCanonicalFileName) {
+        var nonCanonicalizedPath = isRootedDiskPath(fileName)
+            ? normalizePath(fileName)
+            : getNormalizedAbsolutePath(fileName, basePath);
+        return getCanonicalFileName(nonCanonicalizedPath);
+    }
+    ts.toPath = toPath;
+    var Comparison;
+    (function (Comparison) {
+        Comparison[Comparison["LessThan"] = -1] = "LessThan";
+        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
+        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
+    })(Comparison = ts.Comparison || (ts.Comparison = {}));
+    function length(array) {
+        return array ? array.length : 0;
+    }
+    ts.length = length;
+    /**
+     * Iterates through 'array' by index and performs the callback on each element of array until the callback
+     * returns a truthy value, then returns that value.
+     * If no such value is found, the callback is applied to each element of array and undefined is returned.
+     */
+    function forEach(array, callback) {
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                var result = callback(array[i], i);
+                if (result) {
+                    return result;
+                }
+            }
+        }
+        return undefined;
+    }
+    ts.forEach = forEach;
+    /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
+    function firstDefined(array, callback) {
+        for (var i = 0; i < array.length; i++) {
+            var result = callback(array[i], i);
+            if (result !== undefined) {
+                return result;
+            }
+        }
+        return undefined;
+    }
+    ts.firstDefined = firstDefined;
+    function findAncestor(node, callback) {
+        while (node) {
+            var result = callback(node);
+            if (result === "quit") {
+                return undefined;
+            }
+            else if (result) {
+                return node;
+            }
+            node = node.parent;
+        }
+        return undefined;
+    }
+    ts.findAncestor = findAncestor;
+    function zipWith(arrayA, arrayB, callback) {
+        var result = [];
+        Debug.assert(arrayA.length === arrayB.length);
+        for (var i = 0; i < arrayA.length; i++) {
+            result.push(callback(arrayA[i], arrayB[i], i));
+        }
+        return result;
+    }
+    ts.zipWith = zipWith;
+    function zipToMap(keys, values) {
+        Debug.assert(keys.length === values.length);
+        var map = createMap();
+        for (var i = 0; i < keys.length; ++i) {
+            map.set(keys[i], values[i]);
+        }
+        return map;
+    }
+    ts.zipToMap = zipToMap;
+    /**
+     * Iterates through `array` by index and performs the callback on each element of array until the callback
+     * returns a falsey value, then returns false.
+     * If no such value is found, the callback is applied to each element of array and `true` is returned.
+     */
+    function every(array, callback) {
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                if (!callback(array[i], i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    ts.every = every;
+    function find(array, predicate) {
+        for (var i = 0; i < array.length; i++) {
+            var value = array[i];
+            if (predicate(value, i)) {
+                return value;
+            }
+        }
+        return undefined;
+    }
+    ts.find = find;
+    function findLast(array, predicate) {
+        for (var i = array.length - 1; i >= 0; i--) {
+            var value = array[i];
+            if (predicate(value, i)) {
+                return value;
+            }
+        }
+        return undefined;
+    }
+    ts.findLast = findLast;
+    /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
+    function findIndex(array, predicate) {
+        for (var i = 0; i < array.length; i++) {
+            if (predicate(array[i], i)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    ts.findIndex = findIndex;
+    /**
+     * Returns the first truthy result of `callback`, or else fails.
+     * This is like `forEach`, but never returns undefined.
+     */
+    function findMap(array, callback) {
+        for (var i = 0; i < array.length; i++) {
+            var result = callback(array[i], i);
+            if (result) {
+                return result;
+            }
+        }
+        Debug.fail();
+    }
+    ts.findMap = findMap;
+    function contains(array, value) {
+        if (array) {
+            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
+                var v = array_1[_i];
+                if (v === value) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    ts.contains = contains;
+    function indexOf(array, value) {
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                if (array[i] === value) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+    ts.indexOf = indexOf;
+    function indexOfAnyCharCode(text, charCodes, start) {
+        for (var i = start || 0; i < text.length; i++) {
+            if (contains(charCodes, text.charCodeAt(i))) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    ts.indexOfAnyCharCode = indexOfAnyCharCode;
+    function countWhere(array, predicate) {
+        var count = 0;
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                var v = array[i];
+                if (predicate(v, i)) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+    ts.countWhere = countWhere;
+    function filter(array, f) {
+        if (array) {
+            var len = array.length;
+            var i = 0;
+            while (i < len && f(array[i]))
+                i++;
+            if (i < len) {
+                var result = array.slice(0, i);
+                i++;
+                while (i < len) {
+                    var item = array[i];
+                    if (f(item)) {
+                        result.push(item);
+                    }
+                    i++;
+                }
+                return result;
+            }
+        }
+        return array;
+    }
+    ts.filter = filter;
+    function filterMutate(array, f) {
+        var outIndex = 0;
+        for (var i = 0; i < array.length; i++) {
+            if (f(array[i], i, array)) {
+                array[outIndex] = array[i];
+                outIndex++;
+            }
+        }
+        array.length = outIndex;
+    }
+    ts.filterMutate = filterMutate;
+    function clear(array) {
+        array.length = 0;
+    }
+    ts.clear = clear;
+    function map(array, f) {
+        var result;
+        if (array) {
+            result = [];
+            for (var i = 0; i < array.length; i++) {
+                result.push(f(array[i], i));
+            }
+        }
+        return result;
+    }
+    ts.map = map;
+    function sameMap(array, f) {
+        var result;
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                if (result) {
+                    result.push(f(array[i], i));
+                }
+                else {
+                    var item = array[i];
+                    var mapped = f(item, i);
+                    if (item !== mapped) {
+                        result = array.slice(0, i);
+                        result.push(mapped);
+                    }
+                }
+            }
+        }
+        return result || array;
+    }
+    ts.sameMap = sameMap;
+    /**
+     * Flattens an array containing a mix of array or non-array elements.
+     *
+     * @param array The array to flatten.
+     */
+    function flatten(array) {
+        var result;
+        if (array) {
+            result = [];
+            for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
+                var v = array_2[_i];
+                if (v) {
+                    if (isArray(v)) {
+                        addRange(result, v);
+                    }
+                    else {
+                        result.push(v);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+    ts.flatten = flatten;
+    /**
+     * Maps an array. If the mapped value is an array, it is spread into the result.
+     *
+     * @param array The array to map.
+     * @param mapfn The callback used to map the result into one or more values.
+     */
+    function flatMap(array, mapfn) {
+        var result;
+        if (array) {
+            result = [];
+            for (var i = 0; i < array.length; i++) {
+                var v = mapfn(array[i], i);
+                if (v) {
+                    if (isArray(v)) {
+                        addRange(result, v);
+                    }
+                    else {
+                        result.push(v);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+    ts.flatMap = flatMap;
+    function flatMapIter(iter, mapfn) {
+        var result = [];
+        while (true) {
+            var _a = iter.next(), value = _a.value, done = _a.done;
+            if (done)
+                break;
+            var res = mapfn(value);
+            if (res) {
+                if (isArray(res)) {
+                    result.push.apply(result, res);
+                }
+                else {
+                    result.push(res);
+                }
+            }
+        }
+        return result;
+    }
+    ts.flatMapIter = flatMapIter;
+    function sameFlatMap(array, mapfn) {
+        var result;
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                var item = array[i];
+                var mapped = mapfn(item, i);
+                if (result || item !== mapped || isArray(mapped)) {
+                    if (!result) {
+                        result = array.slice(0, i);
+                    }
+                    if (isArray(mapped)) {
+                        addRange(result, mapped);
+                    }
+                    else {
+                        result.push(mapped);
+                    }
+                }
+            }
+        }
+        return result || array;
+    }
+    ts.sameFlatMap = sameFlatMap;
+    function mapDefined(array, mapFn) {
+        var result = [];
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                var item = array[i];
+                var mapped = mapFn(item, i);
+                if (mapped !== undefined) {
+                    result.push(mapped);
+                }
+            }
+        }
+        return result;
+    }
+    ts.mapDefined = mapDefined;
+    function mapDefinedIter(iter, mapFn) {
+        var result = [];
+        while (true) {
+            var _a = iter.next(), value = _a.value, done = _a.done;
+            if (done)
+                break;
+            var res = mapFn(value);
+            if (res !== undefined) {
+                result.push(res);
+            }
+        }
+        return result;
+    }
+    ts.mapDefinedIter = mapDefinedIter;
+    /**
+     * Computes the first matching span of elements and returns a tuple of the first span
+     * and the remaining elements.
+     */
+    function span(array, f) {
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                if (!f(array[i], i)) {
+                    return [array.slice(0, i), array.slice(i)];
+                }
+            }
+            return [array.slice(0), []];
+        }
+        return undefined;
+    }
+    ts.span = span;
+    /**
+     * Maps contiguous spans of values with the same key.
+     *
+     * @param array The array to map.
+     * @param keyfn A callback used to select the key for an element.
+     * @param mapfn A callback used to map a contiguous chunk of values to a single value.
+     */
+    function spanMap(array, keyfn, mapfn) {
+        var result;
+        if (array) {
+            result = [];
+            var len = array.length;
+            var previousKey = void 0;
+            var key = void 0;
+            var start = 0;
+            var pos = 0;
+            while (start < len) {
+                while (pos < len) {
+                    var value = array[pos];
+                    key = keyfn(value, pos);
+                    if (pos === 0) {
+                        previousKey = key;
+                    }
+                    else if (key !== previousKey) {
+                        break;
+                    }
+                    pos++;
+                }
+                if (start < pos) {
+                    var v = mapfn(array.slice(start, pos), previousKey, start, pos);
+                    if (v) {
+                        result.push(v);
+                    }
+                    start = pos;
+                }
+                previousKey = key;
+                pos++;
+            }
+        }
+        return result;
+    }
+    ts.spanMap = spanMap;
+    function mapEntries(map, f) {
+        if (!map) {
+            return undefined;
+        }
+        var result = createMap();
+        map.forEach(function (value, key) {
+            var _a = f(key, value), newKey = _a[0], newValue = _a[1];
+            result.set(newKey, newValue);
+        });
+        return result;
+    }
+    ts.mapEntries = mapEntries;
+    function some(array, predicate) {
+        if (array) {
+            if (predicate) {
+                for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
+                    var v = array_3[_i];
+                    if (predicate(v)) {
+                        return true;
+                    }
+                }
+            }
+            else {
+                return array.length > 0;
+            }
+        }
+        return false;
+    }
+    ts.some = some;
+    function concatenate(array1, array2) {
+        if (!some(array2))
+            return array1;
+        if (!some(array1))
+            return array2;
+        return array1.concat(array2);
+    }
+    ts.concatenate = concatenate;
+    // TODO: fixme (N^2) - add optional comparer so collection can be sorted before deduplication.
+    function deduplicate(array, areEqual) {
+        var result;
+        if (array) {
+            result = [];
+            loop: for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
+                var item = array_4[_i];
+                for (var _a = 0, result_1 = result; _a < result_1.length; _a++) {
+                    var res = result_1[_a];
+                    if (areEqual ? areEqual(res, item) : res === item) {
+                        continue loop;
+                    }
+                }
+                result.push(item);
+            }
+        }
+        return result;
+    }
+    ts.deduplicate = deduplicate;
+    function arrayIsEqualTo(array1, array2, equaler) {
+        if (!array1 || !array2) {
+            return array1 === array2;
+        }
+        if (array1.length !== array2.length) {
+            return false;
+        }
+        for (var i = 0; i < array1.length; i++) {
+            var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
+            if (!equals) {
+                return false;
+            }
+        }
+        return true;
+    }
+    ts.arrayIsEqualTo = arrayIsEqualTo;
+    function changesAffectModuleResolution(oldOptions, newOptions) {
+        return !oldOptions ||
+            (oldOptions.module !== newOptions.module) ||
+            (oldOptions.moduleResolution !== newOptions.moduleResolution) ||
+            (oldOptions.noResolve !== newOptions.noResolve) ||
+            (oldOptions.target !== newOptions.target) ||
+            (oldOptions.noLib !== newOptions.noLib) ||
+            (oldOptions.jsx !== newOptions.jsx) ||
+            (oldOptions.allowJs !== newOptions.allowJs) ||
+            (oldOptions.rootDir !== newOptions.rootDir) ||
+            (oldOptions.configFilePath !== newOptions.configFilePath) ||
+            (oldOptions.baseUrl !== newOptions.baseUrl) ||
+            (oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
+            !arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
+            !arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
+            !arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
+            !equalOwnProperties(oldOptions.paths, newOptions.paths);
+    }
+    ts.changesAffectModuleResolution = changesAffectModuleResolution;
+    function compact(array) {
+        var result;
+        if (array) {
+            for (var i = 0; i < array.length; i++) {
+                var v = array[i];
+                if (result || !v) {
+                    if (!result) {
+                        result = array.slice(0, i);
+                    }
+                    if (v) {
+                        result.push(v);
+                    }
+                }
+            }
+        }
+        return result || array;
+    }
+    ts.compact = compact;
+    /**
+     * Gets the relative complement of `arrayA` with respect to `b`, returning the elements that
+     * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
+     * based on the provided comparer.
+     */
+    function relativeComplement(arrayA, arrayB, comparer, offsetA, offsetB) {
+        if (comparer === void 0) { comparer = compareValues; }
+        if (offsetA === void 0) { offsetA = 0; }
+        if (offsetB === void 0) { offsetB = 0; }
+        if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0)
+            return arrayB;
+        var result = [];
+        outer: for (; offsetB < arrayB.length; offsetB++) {
+            inner: for (; offsetA < arrayA.length; offsetA++) {
+                switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
+                    case -1 /* LessThan */: break inner;
+                    case 0 /* EqualTo */: continue outer;
+                    case 1 /* GreaterThan */: continue inner;
+                }
+            }
+            result.push(arrayB[offsetB]);
+        }
+        return result;
+    }
+    ts.relativeComplement = relativeComplement;
+    function sum(array, prop) {
+        var result = 0;
+        for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
+            var v = array_5[_i];
+            // Note: we need the following type assertion because of GH #17069
+            result += v[prop];
+        }
+        return result;
+    }
+    ts.sum = sum;
+    /**
+     * Appends a value to an array, returning the array.
+     *
+     * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
+     * is created if `value` was appended.
+     * @param value The value to append to the array. If `value` is `undefined`, nothing is
+     * appended.
+     */
+    function append(to, value) {
+        if (value === undefined)
+            return to;
+        if (to === undefined)
+            return [value];
+        to.push(value);
+        return to;
+    }
+    ts.append = append;
+    /**
+     * Gets the actual offset into an array for a relative offset. Negative offsets indicate a
+     * position offset from the end of the array.
+     */
+    function toOffset(array, offset) {
+        return offset < 0 ? array.length + offset : offset;
+    }
+    /**
+     * Appends a range of value to an array, returning the array.
+     *
+     * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
+     * is created if `value` was appended.
+     * @param from The values to append to the array. If `from` is `undefined`, nothing is
+     * appended. If an element of `from` is `undefined`, that element is not appended.
+     * @param start The offset in `from` at which to start copying values.
+     * @param end The offset in `from` at which to stop copying values (non-inclusive).
+     */
+    function addRange(to, from, start, end) {
+        if (from === undefined || from.length === 0)
+            return to;
+        if (to === undefined)
+            return from.slice(start, end);
+        start = start === undefined ? 0 : toOffset(from, start);
+        end = end === undefined ? from.length : toOffset(from, end);
+        for (var i = start; i < end && i < from.length; i++) {
+            var v = from[i];
+            if (v !== undefined) {
+                to.push(from[i]);
+            }
+        }
+        return to;
+    }
+    ts.addRange = addRange;
+    /**
+     * @return Whether the value was added.
+     */
+    function pushIfUnique(array, toAdd) {
+        if (contains(array, toAdd)) {
+            return false;
+        }
+        else {
+            array.push(toAdd);
+            return true;
+        }
+    }
+    ts.pushIfUnique = pushIfUnique;
+    /**
+     * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
+     */
+    function appendIfUnique(array, toAdd) {
+        if (array) {
+            pushIfUnique(array, toAdd);
+            return array;
+        }
+        else {
+            return [toAdd];
+        }
+    }
+    ts.appendIfUnique = appendIfUnique;
+    /**
+     * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
+     */
+    function stableSort(array, comparer) {
+        if (comparer === void 0) { comparer = compareValues; }
+        return array
+            .map(function (_, i) { return i; }) // create array of indices
+            .sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); }) // sort indices by value then position
+            .map(function (i) { return array[i]; }); // get sorted array
+    }
+    ts.stableSort = stableSort;
+    function rangeEquals(array1, array2, pos, end) {
+        while (pos < end) {
+            if (array1[pos] !== array2[pos]) {
+                return false;
+            }
+            pos++;
+        }
+        return true;
+    }
+    ts.rangeEquals = rangeEquals;
+    /**
+     * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
+     * A negative offset indicates the element should be retrieved from the end of the array.
+     */
+    function elementAt(array, offset) {
+        if (array) {
+            offset = toOffset(array, offset);
+            if (offset < array.length) {
+                return array[offset];
+            }
+        }
+        return undefined;
+    }
+    ts.elementAt = elementAt;
+    /**
+     * Returns the first element of an array if non-empty, `undefined` otherwise.
+     */
+    function firstOrUndefined(array) {
+        return elementAt(array, 0);
+    }
+    ts.firstOrUndefined = firstOrUndefined;
+    function first(array) {
+        Debug.assert(array.length !== 0);
+        return array[0];
+    }
+    ts.first = first;
+    /**
+     * Returns the last element of an array if non-empty, `undefined` otherwise.
+     */
+    function lastOrUndefined(array) {
+        return elementAt(array, -1);
+    }
+    ts.lastOrUndefined = lastOrUndefined;
+    function last(array) {
+        Debug.assert(array.length !== 0);
+        return array[array.length - 1];
+    }
+    ts.last = last;
+    /**
+     * Returns the only element of an array if it contains only one element, `undefined` otherwise.
+     */
+    function singleOrUndefined(array) {
+        return array && array.length === 1
+            ? array[0]
+            : undefined;
+    }
+    ts.singleOrUndefined = singleOrUndefined;
+    function singleOrMany(array) {
+        return array && array.length === 1
+            ? array[0]
+            : array;
+    }
+    ts.singleOrMany = singleOrMany;
+    function replaceElement(array, index, value) {
+        var result = array.slice(0);
+        result[index] = value;
+        return result;
+    }
+    ts.replaceElement = replaceElement;
+    /**
+     * Performs a binary search, finding the index at which 'value' occurs in 'array'.
+     * If no such index is found, returns the 2's-complement of first index at which
+     * number[index] exceeds number.
+     * @param array A sorted array whose first element must be no larger than number
+     * @param number The value to be searched for in the array.
+     */
+    function binarySearch(array, value, comparer, offset) {
+        if (!array || array.length === 0) {
+            return -1;
+        }
+        var low = offset || 0;
+        var high = array.length - 1;
+        comparer = comparer !== undefined
+            ? comparer
+            : function (v1, v2) { return (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0)); };
+        while (low <= high) {
+            var middle = low + ((high - low) >> 1);
+            var midValue = array[middle];
+            if (comparer(midValue, value) === 0) {
+                return middle;
+            }
+            else if (comparer(midValue, value) > 0) {
+                high = middle - 1;
+            }
+            else {
+                low = middle + 1;
+            }
+        }
+        return ~low;
+    }
+    ts.binarySearch = binarySearch;
+    function reduceLeft(array, f, initial, start, count) {
+        if (array && array.length > 0) {
+            var size = array.length;
+            if (size > 0) {
+                var pos = start === undefined || start < 0 ? 0 : start;
+                var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count;
+                var result = void 0;
+                if (arguments.length <= 2) {
+                    result = array[pos];
+                    pos++;
+                }
+                else {
+                    result = initial;
+                }
+                while (pos <= end) {
+                    result = f(result, array[pos], pos);
+                    pos++;
+                }
+                return result;
+            }
+        }
+        return initial;
+    }
+    ts.reduceLeft = reduceLeft;
+    function reduceRight(array, f, initial, start, count) {
+        if (array) {
+            var size = array.length;
+            if (size > 0) {
+                var pos = start === undefined || start > size - 1 ? size - 1 : start;
+                var end = count === undefined || pos - count < 0 ? 0 : pos - count;
+                var result = void 0;
+                if (arguments.length <= 2) {
+                    result = array[pos];
+                    pos--;
+                }
+                else {
+                    result = initial;
+                }
+                while (pos >= end) {
+                    result = f(result, array[pos], pos);
+                    pos--;
+                }
+                return result;
+            }
+        }
+        return initial;
+    }
+    ts.reduceRight = reduceRight;
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+    /**
+     * Indicates whether a map-like contains an own property with the specified key.
+     *
+     * @param map A map-like.
+     * @param key A property key.
+     */
+    function hasProperty(map, key) {
+        return hasOwnProperty.call(map, key);
+    }
+    ts.hasProperty = hasProperty;
+    /**
+     * Gets the value of an owned property in a map-like.
+     *
+     * @param map A map-like.
+     * @param key A property key.
+     */
+    function getProperty(map, key) {
+        return hasOwnProperty.call(map, key) ? map[key] : undefined;
+    }
+    ts.getProperty = getProperty;
+    /**
+     * Gets the owned, enumerable property keys of a map-like.
+     */
+    function getOwnKeys(map) {
+        var keys = [];
+        for (var key in map) {
+            if (hasOwnProperty.call(map, key)) {
+                keys.push(key);
+            }
+        }
+        return keys;
+    }
+    ts.getOwnKeys = getOwnKeys;
+    function getOwnValues(sparseArray) {
+        var values = [];
+        for (var key in sparseArray) {
+            if (hasOwnProperty.call(sparseArray, key)) {
+                values.push(sparseArray[key]);
+            }
+        }
+        return values;
+    }
+    ts.getOwnValues = getOwnValues;
+    function arrayFrom(iterator, map) {
+        var result = [];
+        for (var _a = iterator.next(), value = _a.value, done = _a.done; !done; _b = iterator.next(), value = _b.value, done = _b.done, _b) {
+            result.push(map ? map(value) : value);
+        }
+        return result;
+        var _b;
+    }
+    ts.arrayFrom = arrayFrom;
+    function forEachEntry(map, callback) {
+        var iterator = map.entries();
+        for (var _a = iterator.next(), pair = _a.value, done = _a.done; !done; _b = iterator.next(), pair = _b.value, done = _b.done, _b) {
+            var key = pair[0], value = pair[1];
+            var result = callback(value, key);
+            if (result) {
+                return result;
+            }
+        }
+        return undefined;
+        var _b;
+    }
+    ts.forEachEntry = forEachEntry;
+    function forEachKey(map, callback) {
+        var iterator = map.keys();
+        for (var _a = iterator.next(), key = _a.value, done = _a.done; !done; _b = iterator.next(), key = _b.value, done = _b.done, _b) {
+            var result = callback(key);
+            if (result) {
+                return result;
+            }
+        }
+        return undefined;
+        var _b;
+    }
+    ts.forEachKey = forEachKey;
+    function copyEntries(source, target) {
+        source.forEach(function (value, key) {
+            target.set(key, value);
+        });
+    }
+    ts.copyEntries = copyEntries;
+    function assign(t) {
+        var args = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            args[_i - 1] = arguments[_i];
+        }
+        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
+            var arg = args_1[_a];
+            for (var p in arg) {
+                if (hasProperty(arg, p)) {
+                    t[p] = arg[p];
+                }
+            }
+        }
+        return t;
+    }
+    ts.assign = assign;
+    /**
+     * Performs a shallow equality comparison of the contents of two map-likes.
+     *
+     * @param left A map-like whose properties should be compared.
+     * @param right A map-like whose properties should be compared.
+     */
+    function equalOwnProperties(left, right, equalityComparer) {
+        if (left === right)
+            return true;
+        if (!left || !right)
+            return false;
+        for (var key in left) {
+            if (hasOwnProperty.call(left, key)) {
+                if (!hasOwnProperty.call(right, key) === undefined)
+                    return false;
+                if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key])
+                    return false;
+            }
+        }
+        for (var key in right) {
+            if (hasOwnProperty.call(right, key)) {
+                if (!hasOwnProperty.call(left, key))
+                    return false;
+            }
+        }
+        return true;
+    }
+    ts.equalOwnProperties = equalOwnProperties;
+    function arrayToMap(array, makeKey, makeValue) {
+        var result = createMap();
+        for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
+            var value = array_6[_i];
+            result.set(makeKey(value), makeValue ? makeValue(value) : value);
+        }
+        return result;
+    }
+    ts.arrayToMap = arrayToMap;
+    function arrayToNumericMap(array, makeKey) {
+        var result = [];
+        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
+            var value = array_7[_i];
+            result[makeKey(value)] = value;
+        }
+        return result;
+    }
+    ts.arrayToNumericMap = arrayToNumericMap;
+    function arrayToSet(array, makeKey) {
+        return arrayToMap(array, makeKey || (function (s) { return s; }), function () { return true; });
+    }
+    ts.arrayToSet = arrayToSet;
+    function cloneMap(map) {
+        var clone = createMap();
+        copyEntries(map, clone);
+        return clone;
+    }
+    ts.cloneMap = cloneMap;
+    function clone(object) {
+        var result = {};
+        for (var id in object) {
+            if (hasOwnProperty.call(object, id)) {
+                result[id] = object[id];
+            }
+        }
+        return result;
+    }
+    ts.clone = clone;
+    function extend(first, second) {
+        var result = {};
+        for (var id in second) {
+            if (hasOwnProperty.call(second, id)) {
+                result[id] = second[id];
+            }
+        }
+        for (var id in first) {
+            if (hasOwnProperty.call(first, id)) {
+                result[id] = first[id];
+            }
+        }
+        return result;
+    }
+    ts.extend = extend;
+    function createMultiMap() {
+        var map = createMap();
+        map.add = multiMapAdd;
+        map.remove = multiMapRemove;
+        return map;
+    }
+    ts.createMultiMap = createMultiMap;
+    function multiMapAdd(key, value) {
+        var values = this.get(key);
+        if (values) {
+            values.push(value);
+        }
+        else {
+            this.set(key, values = [value]);
+        }
+        return values;
+    }
+    function multiMapRemove(key, value) {
+        var values = this.get(key);
+        if (values) {
+            unorderedRemoveItem(values, value);
+            if (!values.length) {
+                this.delete(key);
+            }
+        }
+    }
+    /**
+     * Tests whether a value is an array.
+     */
+    function isArray(value) {
+        return Array.isArray ? Array.isArray(value) : value instanceof Array;
+    }
+    ts.isArray = isArray;
+    /**
+     * Tests whether a value is string
+     */
+    function isString(text) {
+        return typeof text === "string";
+    }
+    ts.isString = isString;
+    function tryCast(value, test) {
+        return value !== undefined && test(value) ? value : undefined;
+    }
+    ts.tryCast = tryCast;
+    function cast(value, test) {
+        if (value !== undefined && test(value))
+            return value;
+        Debug.fail("Invalid cast. The supplied value did not pass the test '" + Debug.getFunctionName(test) + "'.");
+    }
+    ts.cast = cast;
+    /** Does nothing. */
+    function noop() { }
+    ts.noop = noop;
+    /** Do nothing and return false */
+    function returnFalse() { return false; }
+    ts.returnFalse = returnFalse;
+    /** Do nothing and return true */
+    function returnTrue() { return true; }
+    ts.returnTrue = returnTrue;
+    /** Returns its argument. */
+    function identity(x) { return x; }
+    ts.identity = identity;
+    /** Throws an error because a function is not implemented. */
+    function notImplemented() {
+        throw new Error("Not implemented");
+    }
+    ts.notImplemented = notImplemented;
+    function memoize(callback) {
+        var value;
+        return function () {
+            if (callback) {
+                value = callback();
+                callback = undefined;
+            }
+            return value;
+        };
+    }
+    ts.memoize = memoize;
+    function chain(a, b, c, d, e) {
+        if (e) {
+            var args_2 = [];
+            for (var i = 0; i < arguments.length; i++) {
+                args_2[i] = arguments[i];
+            }
+            return function (t) { return compose.apply(void 0, map(args_2, function (f) { return f(t); })); };
+        }
+        else if (d) {
+            return function (t) { return compose(a(t), b(t), c(t), d(t)); };
+        }
+        else if (c) {
+            return function (t) { return compose(a(t), b(t), c(t)); };
+        }
+        else if (b) {
+            return function (t) { return compose(a(t), b(t)); };
+        }
+        else if (a) {
+            return function (t) { return compose(a(t)); };
+        }
+        else {
+            return function (_) { return function (u) { return u; }; };
+        }
+    }
+    ts.chain = chain;
+    function compose(a, b, c, d, e) {
+        if (e) {
+            var args_3 = [];
+            for (var i = 0; i < arguments.length; i++) {
+                args_3[i] = arguments[i];
+            }
+            return function (t) { return reduceLeft(args_3, function (u, f) { return f(u); }, t); };
+        }
+        else if (d) {
+            return function (t) { return d(c(b(a(t)))); };
+        }
+        else if (c) {
+            return function (t) { return c(b(a(t))); };
+        }
+        else if (b) {
+            return function (t) { return b(a(t)); };
+        }
+        else if (a) {
+            return function (t) { return a(t); };
+        }
+        else {
+            return function (t) { return t; };
+        }
+    }
+    ts.compose = compose;
+    function formatStringFromArgs(text, args, baseIndex) {
+        baseIndex = baseIndex || 0;
+        return text.replace(/{(\d+)}/g, function (_match, index) { return args[+index + baseIndex]; });
+    }
+    ts.formatStringFromArgs = formatStringFromArgs;
+    ts.localizedDiagnosticMessages = undefined;
+    function getLocaleSpecificMessage(message) {
+        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message;
+    }
+    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
+    function createFileDiagnostic(file, start, length, message) {
+        Debug.assertGreaterThanOrEqual(start, 0);
+        Debug.assertGreaterThanOrEqual(length, 0);
+        if (file) {
+            Debug.assertLessThanOrEqual(start, file.text.length);
+            Debug.assertLessThanOrEqual(start + length, file.text.length);
+        }
+        var text = getLocaleSpecificMessage(message);
+        if (arguments.length > 4) {
+            text = formatStringFromArgs(text, arguments, 4);
+        }
+        return {
+            file: file,
+            start: start,
+            length: length,
+            messageText: text,
+            category: message.category,
+            code: message.code,
+        };
+    }
+    ts.createFileDiagnostic = createFileDiagnostic;
+    /* internal */
+    function formatMessage(_dummy, message) {
+        var text = getLocaleSpecificMessage(message);
+        if (arguments.length > 2) {
+            text = formatStringFromArgs(text, arguments, 2);
+        }
+        return text;
+    }
+    ts.formatMessage = formatMessage;
+    function createCompilerDiagnostic(message) {
+        var text = getLocaleSpecificMessage(message);
+        if (arguments.length > 1) {
+            text = formatStringFromArgs(text, arguments, 1);
+        }
+        return {
+            file: undefined,
+            start: undefined,
+            length: undefined,
+            messageText: text,
+            category: message.category,
+            code: message.code
+        };
+    }
+    ts.createCompilerDiagnostic = createCompilerDiagnostic;
+    function createCompilerDiagnosticFromMessageChain(chain) {
+        return {
+            file: undefined,
+            start: undefined,
+            length: undefined,
+            code: chain.code,
+            category: chain.category,
+            messageText: chain.next ? chain : chain.messageText
+        };
+    }
+    ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain;
+    function chainDiagnosticMessages(details, message) {
+        var text = getLocaleSpecificMessage(message);
+        if (arguments.length > 2) {
+            text = formatStringFromArgs(text, arguments, 2);
+        }
+        return {
+            messageText: text,
+            category: message.category,
+            code: message.code,
+            next: details
+        };
+    }
+    ts.chainDiagnosticMessages = chainDiagnosticMessages;
+    function concatenateDiagnosticMessageChains(headChain, tailChain) {
+        var lastChain = headChain;
+        while (lastChain.next) {
+            lastChain = lastChain.next;
+        }
+        lastChain.next = tailChain;
+        return headChain;
+    }
+    ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
+    function compareValues(a, b) {
+        if (a === b)
+            return 0 /* EqualTo */;
+        if (a === undefined)
+            return -1 /* LessThan */;
+        if (b === undefined)
+            return 1 /* GreaterThan */;
+        return a < b ? -1 /* LessThan */ : 1 /* GreaterThan */;
+    }
+    ts.compareValues = compareValues;
+    function compareStrings(a, b, ignoreCase) {
+        if (a === b)
+            return 0 /* EqualTo */;
+        if (a === undefined)
+            return -1 /* LessThan */;
+        if (b === undefined)
+            return 1 /* GreaterThan */;
+        if (ignoreCase) {
+            // Checking if "collator exists indicates that Intl is available.
+            // We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre"
+            if (ts.collator) {
+                var result = ts.localeCompareIsCorrect ?
+                    ts.collator.compare(a, b) :
+                    a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A
+                return result < 0 ? -1 /* LessThan */ : result > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */;
+            }
+            a = a.toUpperCase();
+            b = b.toUpperCase();
+            if (a === b)
+                return 0 /* EqualTo */;
+        }
+        return a < b ? -1 /* LessThan */ : 1 /* GreaterThan */;
+    }
+    ts.compareStrings = compareStrings;
+    function compareStringsCaseInsensitive(a, b) {
+        return compareStrings(a, b, /*ignoreCase*/ true);
+    }
+    ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive;
+    function getDiagnosticFileName(diagnostic) {
+        return diagnostic.file ? diagnostic.file.fileName : undefined;
+    }
+    function compareDiagnostics(d1, d2) {
+        return compareValues(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) ||
+            compareValues(d1.start, d2.start) ||
+            compareValues(d1.length, d2.length) ||
+            compareValues(d1.code, d2.code) ||
+            compareMessageText(d1.messageText, d2.messageText) ||
+            0 /* EqualTo */;
+    }
+    ts.compareDiagnostics = compareDiagnostics;
+    function compareMessageText(text1, text2) {
+        while (text1 && text2) {
+            // We still have both chains.
+            var string1 = isString(text1) ? text1 : text1.messageText;
+            var string2 = isString(text2) ? text2 : text2.messageText;
+            var res = compareValues(string1, string2);
+            if (res) {
+                return res;
+            }
+            text1 = isString(text1) ? undefined : text1.next;
+            text2 = isString(text2) ? undefined : text2.next;
+        }
+        if (!text1 && !text2) {
+            // if the chains are done, then these messages are the same.
+            return 0 /* EqualTo */;
+        }
+        // We still have one chain remaining.  The shorter chain should come first.
+        return text1 ? 1 /* GreaterThan */ : -1 /* LessThan */;
+    }
+    function sortAndDeduplicateDiagnostics(diagnostics) {
+        return deduplicateSortedDiagnostics(diagnostics.sort(compareDiagnostics));
+    }
+    ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics;
+    function deduplicateSortedDiagnostics(diagnostics) {
+        if (diagnostics.length < 2) {
+            return diagnostics;
+        }
+        var newDiagnostics = [diagnostics[0]];
+        var previousDiagnostic = diagnostics[0];
+        for (var i = 1; i < diagnostics.length; i++) {
+            var currentDiagnostic = diagnostics[i];
+            var isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === 0 /* EqualTo */;
+            if (!isDupe) {
+                newDiagnostics.push(currentDiagnostic);
+                previousDiagnostic = currentDiagnostic;
+            }
+        }
+        return newDiagnostics;
+    }
+    ts.deduplicateSortedDiagnostics = deduplicateSortedDiagnostics;
+    function normalizeSlashes(path) {
+        return path.replace(/\\/g, "/");
+    }
+    ts.normalizeSlashes = normalizeSlashes;
+    /**
+     * Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
+     */
+    function getRootLength(path) {
+        if (path.charCodeAt(0) === 47 /* slash */) {
+            if (path.charCodeAt(1) !== 47 /* slash */)
+                return 1;
+            var p1 = path.indexOf("/", 2);
+            if (p1 < 0)
+                return 2;
+            var p2 = path.indexOf("/", p1 + 1);
+            if (p2 < 0)
+                return p1 + 1;
+            return p2 + 1;
+        }
+        if (path.charCodeAt(1) === 58 /* colon */) {
+            if (path.charCodeAt(2) === 47 /* slash */)
+                return 3;
+            return 2;
+        }
+        // Per RFC 1738 'file' URI schema has the shape file://<host>/<path>
+        // if <host> is omitted then it is assumed that host value is 'localhost',
+        // however slash after the omitted <host> is not removed.
+        // file:///folder1/file1 - this is a correct URI
+        // file://folder2/file2 - this is an incorrect URI
+        if (path.lastIndexOf("file:///", 0) === 0) {
+            return "file:///".length;
+        }
+        var idx = path.indexOf("://");
+        if (idx !== -1) {
+            return idx + "://".length;
+        }
+        return 0;
+    }
+    ts.getRootLength = getRootLength;
+    /**
+     * Internally, we represent paths as strings with '/' as the directory separator.
+     * When we make system calls (eg: LanguageServiceHost.getDirectory()),
+     * we expect the host to correctly handle paths in our specified format.
+     */
+    ts.directorySeparator = "/";
+    var directorySeparatorCharCode = 47 /* slash */;
+    function getNormalizedParts(normalizedSlashedPath, rootLength) {
+        var parts = normalizedSlashedPath.substr(rootLength).split(ts.directorySeparator);
+        var normalized = [];
+        for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
+            var part = parts_1[_i];
+            if (part !== ".") {
+                if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") {
+                    normalized.pop();
+                }
+                else {
+                    // A part may be an empty string (which is 'falsy') if the path had consecutive slashes,
+                    // e.g. "path//file.ts".  Drop these before re-joining the parts.
+                    if (part) {
+                        normalized.push(part);
+                    }
+                }
+            }
+        }
+        return normalized;
+    }
+    function normalizePath(path) {
+        return normalizePathAndParts(path).path;
+    }
+    ts.normalizePath = normalizePath;
+    function normalizePathAndParts(path) {
+        path = normalizeSlashes(path);
+        var rootLength = getRootLength(path);
+        var root = path.substr(0, rootLength);
+        var parts = getNormalizedParts(path, rootLength);
+        if (parts.length) {
+            var joinedParts = root + parts.join(ts.directorySeparator);
+            return { path: pathEndsWithDirectorySeparator(path) ? joinedParts + ts.directorySeparator : joinedParts, parts: parts };
+        }
+        else {
+            return { path: root, parts: parts };
+        }
+    }
+    ts.normalizePathAndParts = normalizePathAndParts;
+    /** A path ending with '/' refers to a directory only, never a file. */
+    function pathEndsWithDirectorySeparator(path) {
+        return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
+    }
+    ts.pathEndsWithDirectorySeparator = pathEndsWithDirectorySeparator;
+    function getDirectoryPath(path) {
+        return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator)));
+    }
+    ts.getDirectoryPath = getDirectoryPath;
+    function isUrl(path) {
+        return path && !isRootedDiskPath(path) && stringContains(path, "://");
+    }
+    ts.isUrl = isUrl;
+    function pathIsRelative(path) {
+        return /^\.\.?($|[\\/])/.test(path);
+    }
+    ts.pathIsRelative = pathIsRelative;
+    /** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */
+    function moduleHasNonRelativeName(moduleName) {
+        return !ts.isExternalModuleNameRelative(moduleName);
+    }
+    ts.moduleHasNonRelativeName = moduleHasNonRelativeName;
+    function getEmitScriptTarget(compilerOptions) {
+        return compilerOptions.target || 0 /* ES3 */;
+    }
+    ts.getEmitScriptTarget = getEmitScriptTarget;
+    function getEmitModuleKind(compilerOptions) {
+        return typeof compilerOptions.module === "number" ?
+            compilerOptions.module :
+            getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS;
+    }
+    ts.getEmitModuleKind = getEmitModuleKind;
+    function getEmitModuleResolutionKind(compilerOptions) {
+        var moduleResolution = compilerOptions.moduleResolution;
+        if (moduleResolution === undefined) {
+            moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
+        }
+        return moduleResolution;
+    }
+    ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind;
+    function hasZeroOrOneAsteriskCharacter(str) {
+        var seenAsterisk = false;
+        for (var i = 0; i < str.length; i++) {
+            if (str.charCodeAt(i) === 42 /* asterisk */) {
+                if (!seenAsterisk) {
+                    seenAsterisk = true;
+                }
+                else {
+                    // have already seen asterisk
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter;
+    function isRootedDiskPath(path) {
+        return path && getRootLength(path) !== 0;
+    }
+    ts.isRootedDiskPath = isRootedDiskPath;
+    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
+        return !isRootedDiskPath(absoluteOrRelativePath)
+            ? absoluteOrRelativePath
+            : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
+    }
+    ts.convertToRelativePath = convertToRelativePath;
+    function normalizedPathComponents(path, rootLength) {
+        var normalizedParts = getNormalizedParts(path, rootLength);
+        return [path.substr(0, rootLength)].concat(normalizedParts);
+    }
+    function getNormalizedPathComponents(path, currentDirectory) {
+        path = normalizeSlashes(path);
+        var rootLength = getRootLength(path);
+        if (rootLength === 0) {
+            // If the path is not rooted it is relative to current directory
+            path = combinePaths(normalizeSlashes(currentDirectory), path);
+            rootLength = getRootLength(path);
+        }
+        return normalizedPathComponents(path, rootLength);
+    }
+    ts.getNormalizedPathComponents = getNormalizedPathComponents;
+    function getNormalizedAbsolutePath(fileName, currentDirectory) {
+        return getNormalizedPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
+    }
+    ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
+    function getNormalizedPathFromPathComponents(pathComponents) {
+        if (pathComponents && pathComponents.length) {
+            return pathComponents[0] + pathComponents.slice(1).join(ts.directorySeparator);
+        }
+    }
+    ts.getNormalizedPathFromPathComponents = getNormalizedPathFromPathComponents;
+    function getNormalizedPathComponentsOfUrl(url) {
+        // Get root length of http://www.website.com/folder1/folder2/
+        // In this example the root is:  http://www.website.com/
+        // normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
+        var urlLength = url.length;
+        // Initial root length is http:// part
+        var rootLength = url.indexOf("://") + "://".length;
+        while (rootLength < urlLength) {
+            // Consume all immediate slashes in the protocol
+            // eg.initial rootlength is just file:// but it needs to consume another "/" in file:///
+            if (url.charCodeAt(rootLength) === 47 /* slash */) {
+                rootLength++;
+            }
+            else {
+                // non slash character means we continue proceeding to next component of root search
+                break;
+            }
+        }
+        // there are no parts after http:// just return current string as the pathComponent
+        if (rootLength === urlLength) {
+            return [url];
+        }
+        // Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://)
+        var indexOfNextSlash = url.indexOf(ts.directorySeparator, rootLength);
+        if (indexOfNextSlash !== -1) {
+            // Found the "/" after the website.com so the root is length of http://www.website.com/
+            // and get components after the root normally like any other folder components
+            rootLength = indexOfNextSlash + 1;
+            return normalizedPathComponents(url, rootLength);
+        }
+        else {
+            // Can't find the host assume the rest of the string as component
+            // but make sure we append "/"  to it as root is not joined using "/"
+            // eg. if url passed in was http://website.com we want to use root as [http://website.com/]
+            // so that other path manipulations will be correct and it can be merged with relative paths correctly
+            return [url + ts.directorySeparator];
+        }
+    }
+    function getNormalizedPathOrUrlComponents(pathOrUrl, currentDirectory) {
+        if (isUrl(pathOrUrl)) {
+            return getNormalizedPathComponentsOfUrl(pathOrUrl);
+        }
+        else {
+            return getNormalizedPathComponents(pathOrUrl, currentDirectory);
+        }
+    }
+    function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
+        var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
+        var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
+        if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
+            // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
+            // that is  ["test", "cases", ""] needs to be actually ["test", "cases"]
+            directoryComponents.pop();
+        }
+        // Find the component that differs
+        var joinStartIndex;
+        for (joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
+            if (getCanonicalFileName(directoryComponents[joinStartIndex]) !== getCanonicalFileName(pathComponents[joinStartIndex])) {
+                break;
+            }
+        }
+        // Get the relative path
+        if (joinStartIndex) {
+            var relativePath = "";
+            var relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
+            for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
+                if (directoryComponents[joinStartIndex] !== "") {
+                    relativePath = relativePath + ".." + ts.directorySeparator;
+                }
+            }
+            return relativePath + relativePathComponents.join(ts.directorySeparator);
+        }
+        // Cant find the relative path, get the absolute path
+        var absolutePath = getNormalizedPathFromPathComponents(pathComponents);
+        if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) {
+            absolutePath = "file:///" + absolutePath;
+        }
+        return absolutePath;
+    }
+    ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
+    function getBaseFileName(path) {
+        if (path === undefined) {
+            return undefined;
+        }
+        var i = path.lastIndexOf(ts.directorySeparator);
+        return i < 0 ? path : path.substring(i + 1);
+    }
+    ts.getBaseFileName = getBaseFileName;
+    function combinePaths(path1, path2) {
+        if (!(path1 && path1.length))
+            return path2;
+        if (!(path2 && path2.length))
+            return path1;
+        if (getRootLength(path2) !== 0)
+            return path2;
+        if (path1.charAt(path1.length - 1) === ts.directorySeparator)
+            return path1 + path2;
+        return path1 + ts.directorySeparator + path2;
+    }
+    ts.combinePaths = combinePaths;
+    function removeTrailingDirectorySeparator(path) {
+        if (path.charAt(path.length - 1) === ts.directorySeparator) {
+            return path.substr(0, path.length - 1);
+        }
+        return path;
+    }
+    ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator;
+    /**
+     * Adds a trailing directory separator to a path, if it does not already have one.
+     * @param path The path.
+     */
+    function ensureTrailingDirectorySeparator(path) {
+        if (path.charAt(path.length - 1) !== ts.directorySeparator) {
+            return path + ts.directorySeparator;
+        }
+        return path;
+    }
+    ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator;
+    function comparePaths(a, b, currentDirectory, ignoreCase) {
+        if (a === b)
+            return 0 /* EqualTo */;
+        if (a === undefined)
+            return -1 /* LessThan */;
+        if (b === undefined)
+            return 1 /* GreaterThan */;
+        a = removeTrailingDirectorySeparator(a);
+        b = removeTrailingDirectorySeparator(b);
+        var aComponents = getNormalizedPathComponents(a, currentDirectory);
+        var bComponents = getNormalizedPathComponents(b, currentDirectory);
+        var sharedLength = Math.min(aComponents.length, bComponents.length);
+        for (var i = 0; i < sharedLength; i++) {
+            var result = compareStrings(aComponents[i], bComponents[i], ignoreCase);
+            if (result !== 0 /* EqualTo */) {
+                return result;
+            }
+        }
+        return compareValues(aComponents.length, bComponents.length);
+    }
+    ts.comparePaths = comparePaths;
+    function containsPath(parent, child, currentDirectory, ignoreCase) {
+        if (parent === undefined || child === undefined)
+            return false;
+        if (parent === child)
+            return true;
+        parent = removeTrailingDirectorySeparator(parent);
+        child = removeTrailingDirectorySeparator(child);
+        if (parent === child)
+            return true;
+        var parentComponents = getNormalizedPathComponents(parent, currentDirectory);
+        var childComponents = getNormalizedPathComponents(child, currentDirectory);
+        if (childComponents.length < parentComponents.length) {
+            return false;
+        }
+        for (var i = 0; i < parentComponents.length; i++) {
+            var result = compareStrings(parentComponents[i], childComponents[i], ignoreCase);
+            if (result !== 0 /* EqualTo */) {
+                return false;
+            }
+        }
+        return true;
+    }
+    ts.containsPath = containsPath;
+    function startsWith(str, prefix) {
+        return str.lastIndexOf(prefix, 0) === 0;
+    }
+    ts.startsWith = startsWith;
+    function removePrefix(str, prefix) {
+        return startsWith(str, prefix) ? str.substr(prefix.length) : str;
+    }
+    ts.removePrefix = removePrefix;
+    function endsWith(str, suffix) {
+        var expectedPos = str.length - suffix.length;
+        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
+    }
+    ts.endsWith = endsWith;
+    function stringContains(str, substring) {
+        return str.indexOf(substring) !== -1;
+    }
+    ts.stringContains = stringContains;
+    function hasExtension(fileName) {
+        return stringContains(getBaseFileName(fileName), ".");
+    }
+    ts.hasExtension = hasExtension;
+    function fileExtensionIs(path, extension) {
+        return path.length > extension.length && endsWith(path, extension);
+    }
+    ts.fileExtensionIs = fileExtensionIs;
+    function fileExtensionIsOneOf(path, extensions) {
+        for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
+            var extension = extensions_1[_i];
+            if (fileExtensionIs(path, extension)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    ts.fileExtensionIsOneOf = fileExtensionIsOneOf;
+    // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
+    // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
+    // proof.
+    var reservedCharacterPattern = /[^\w\s\/]/g;
+    var wildcardCharCodes = [42 /* asterisk */, 63 /* question */];
+    ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
+    var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))";
+    var filesMatcher = {
+        /**
+         * Matches any single directory segment unless it is the last segment and a .min.js file
+         * Breakdown:
+         *  [^./]                   # matches everything up to the first . character (excluding directory seperators)
+         *  (\\.(?!min\\.js$))?     # matches . characters but not if they are part of the .min.js file extension
+         */
+        singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
+        /**
+         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
+         * files or directories, does not match subdirectories that start with a . character
+         */
+        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
+        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); }
+    };
+    var directoriesMatcher = {
+        singleAsteriskRegexFragment: "[^/]*",
+        /**
+         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
+         * files or directories, does not match subdirectories that start with a . character
+         */
+        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
+        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); }
+    };
+    var excludeMatcher = {
+        singleAsteriskRegexFragment: "[^/]*",
+        doubleAsteriskRegexFragment: "(/.+?)?",
+        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); }
+    };
+    var wildcardMatchers = {
+        files: filesMatcher,
+        directories: directoriesMatcher,
+        exclude: excludeMatcher
+    };
+    function getRegularExpressionForWildcard(specs, basePath, usage) {
+        var patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
+        if (!patterns || !patterns.length) {
+            return undefined;
+        }
+        var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|");
+        // If excluding, match "foo/bar/baz...", but if including, only allow "foo".
+        var terminator = usage === "exclude" ? "($|/)" : "$";
+        return "^(" + pattern + ")" + terminator;
+    }
+    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
+    function getRegularExpressionsForWildcards(specs, basePath, usage) {
+        if (specs === undefined || specs.length === 0) {
+            return undefined;
+        }
+        return flatMap(specs, function (spec) {
+            return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
+        });
+    }
+    /**
+     * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
+     * and does not contain any glob characters itself.
+     */
+    function isImplicitGlob(lastPathComponent) {
+        return !/[.*?]/.test(lastPathComponent);
+    }
+    ts.isImplicitGlob = isImplicitGlob;
+    function getSubPatternFromSpec(spec, basePath, usage, _a) {
+        var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter;
+        var subpattern = "";
+        var hasRecursiveDirectoryWildcard = false;
+        var hasWrittenComponent = false;
+        var components = getNormalizedPathComponents(spec, basePath);
+        var lastComponent = lastOrUndefined(components);
+        if (usage !== "exclude" && lastComponent === "**") {
+            return undefined;
+        }
+        // getNormalizedPathComponents includes the separator for the root component.
+        // We need to remove to create our regex correctly.
+        components[0] = removeTrailingDirectorySeparator(components[0]);
+        if (isImplicitGlob(lastComponent)) {
+            components.push("**", "*");
+        }
+        var optionalCount = 0;
+        for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
+            var component = components_1[_i];
+            if (component === "**") {
+                if (hasRecursiveDirectoryWildcard) {
+                    return undefined;
+                }
+                subpattern += doubleAsteriskRegexFragment;
+                hasRecursiveDirectoryWildcard = true;
+            }
+            else {
+                if (usage === "directories") {
+                    subpattern += "(";
+                    optionalCount++;
+                }
+                if (hasWrittenComponent) {
+                    subpattern += ts.directorySeparator;
+                }
+                if (usage !== "exclude") {
+                    var componentPattern = "";
+                    // The * and ? wildcards should not match directories or files that start with . if they
+                    // appear first in a component. Dotted directories and files can be included explicitly
+                    // like so: **/.*/.*
+                    if (component.charCodeAt(0) === 42 /* asterisk */) {
+                        componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
+                        component = component.substr(1);
+                    }
+                    else if (component.charCodeAt(0) === 63 /* question */) {
+                        componentPattern += "[^./]";
+                        component = component.substr(1);
+                    }
+                    componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
+                    // Patterns should not include subfolders like node_modules unless they are
+                    // explicitly included as part of the path.
+                    //
+                    // As an optimization, if the component pattern is the same as the component,
+                    // then there definitely were no wildcard characters and we do not need to
+                    // add the exclusion pattern.
+                    if (componentPattern !== component) {
+                        subpattern += implicitExcludePathRegexPattern;
+                    }
+                    subpattern += componentPattern;
+                }
+                else {
+                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
+                }
+            }
+            hasWrittenComponent = true;
+        }
+        while (optionalCount > 0) {
+            subpattern += ")?";
+            optionalCount--;
+        }
+        return subpattern;
+    }
+    function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
+        return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
+    }
+    function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
+        path = normalizePath(path);
+        currentDirectory = normalizePath(currentDirectory);
+        var absolutePath = combinePaths(currentDirectory, path);
+        return {
+            includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }),
+            includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
+            includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
+            excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
+            basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
+        };
+    }
+    ts.getFileMatcherPatterns = getFileMatcherPatterns;
+    function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries) {
+        path = normalizePath(path);
+        currentDirectory = normalizePath(currentDirectory);
+        var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
+        var regexFlag = useCaseSensitiveFileNames ? "" : "i";
+        var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return new RegExp(pattern, regexFlag); });
+        var includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag);
+        var excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag);
+        // Associate an array of results with each include regex. This keeps results in order of the "include" order.
+        // If there are no "includes", then just put everything in results[0].
+        var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]];
+        var comparer = useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive;
+        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
+            var basePath = _a[_i];
+            visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
+        }
+        return flatten(results);
+        function visitDirectory(path, absolutePath, depth) {
+            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
+            files = files.slice().sort(comparer);
+            var _loop_1 = function (current) {
+                var name = combinePaths(path, current);
+                var absoluteName = combinePaths(absolutePath, current);
+                if (extensions && !fileExtensionIsOneOf(name, extensions))
+                    return "continue";
+                if (excludeRegex && excludeRegex.test(absoluteName))
+                    return "continue";
+                if (!includeFileRegexes) {
+                    results[0].push(name);
+                }
+                else {
+                    var includeIndex = findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); });
+                    if (includeIndex !== -1) {
+                        results[includeIndex].push(name);
+                    }
+                }
+            };
+            for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
+                var current = files_1[_i];
+                _loop_1(current);
+            }
+            if (depth !== undefined) {
+                depth--;
+                if (depth === 0) {
+                    return;
+                }
+            }
+            directories = directories.slice().sort(comparer);
+            for (var _b = 0, directories_1 = directories; _b < directories_1.length; _b++) {
+                var current = directories_1[_b];
+                var name = combinePaths(path, current);
+                var absoluteName = combinePaths(absolutePath, current);
+                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
+                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
+                    visitDirectory(name, absoluteName, depth);
+                }
+            }
+        }
+    }
+    ts.matchFiles = matchFiles;
+    /**
+     * Computes the unique non-wildcard base paths amongst the provided include patterns.
+     */
+    function getBasePaths(path, includes, useCaseSensitiveFileNames) {
+        // Storage for our results in the form of literal paths (e.g. the paths as written by the user).
+        var basePaths = [path];
+        if (includes) {
+            // Storage for literal base paths amongst the include patterns.
+            var includeBasePaths = [];
+            for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) {
+                var include = includes_1[_i];
+                // We also need to check the relative paths by converting them to absolute and normalizing
+                // in case they escape the base path (e.g "..\somedirectory")
+                var absolute = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include));
+                // Append the literal and canonical candidate base paths.
+                includeBasePaths.push(getIncludeBasePath(absolute));
+            }
+            // Sort the offsets array using either the literal or canonical path representations.
+            includeBasePaths.sort(useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive);
+            var _loop_2 = function (includeBasePath) {
+                if (ts.every(basePaths, function (basePath) { return !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) {
+                    basePaths.push(includeBasePath);
+                }
+            };
+            // Iterate over each include base path and include unique base paths that are not a
+            // subpath of an existing base path
+            for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) {
+                var includeBasePath = includeBasePaths_1[_a];
+                _loop_2(includeBasePath);
+            }
+        }
+        return basePaths;
+    }
+    function getIncludeBasePath(absolute) {
+        var wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
+        if (wildcardOffset < 0) {
+            // No "*" or "?" in the path
+            return !hasExtension(absolute)
+                ? absolute
+                : removeTrailingDirectorySeparator(getDirectoryPath(absolute));
+        }
+        return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
+    }
+    function ensureScriptKind(fileName, scriptKind) {
+        // Using scriptKind as a condition handles both:
+        // - 'scriptKind' is unspecified and thus it is `undefined`
+        // - 'scriptKind' is set and it is `Unknown` (0)
+        // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
+        // to get the ScriptKind from the file name. If it cannot be resolved
+        // from the file name then the default 'TS' script kind is returned.
+        return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */;
+    }
+    ts.ensureScriptKind = ensureScriptKind;
+    function getScriptKindFromFileName(fileName) {
+        var ext = fileName.substr(fileName.lastIndexOf("."));
+        switch (ext.toLowerCase()) {
+            case ".js" /* Js */:
+                return 1 /* JS */;
+            case ".jsx" /* Jsx */:
+                return 2 /* JSX */;
+            case ".ts" /* Ts */:
+                return 3 /* TS */;
+            case ".tsx" /* Tsx */:
+                return 4 /* TSX */;
+            case ".json" /* Json */:
+                return 6 /* JSON */;
+            default:
+                return 0 /* Unknown */;
+        }
+    }
+    ts.getScriptKindFromFileName = getScriptKindFromFileName;
+    /**
+     *  List of supported extensions in order of file resolution precedence.
+     */
+    ts.supportedTypeScriptExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */];
+    /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
+    ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */];
+    ts.supportedJavascriptExtensions = [".js" /* Js */, ".jsx" /* Jsx */];
+    var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions);
+    function getSupportedExtensions(options, extraFileExtensions) {
+        var needAllExtensions = options && options.allowJs;
+        if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
+            return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions;
+        }
+        return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; })));
+    }
+    ts.getSupportedExtensions = getSupportedExtensions;
+    function hasJavaScriptFileExtension(fileName) {
+        return forEach(ts.supportedJavascriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); });
+    }
+    ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
+    function hasTypeScriptFileExtension(fileName) {
+        return forEach(ts.supportedTypeScriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); });
+    }
+    ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension;
+    function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) {
+        if (!fileName) {
+            return false;
+        }
+        for (var _i = 0, _a = getSupportedExtensions(compilerOptions, extraFileExtensions); _i < _a.length; _i++) {
+            var extension = _a[_i];
+            if (fileExtensionIs(fileName, extension)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    ts.isSupportedSourceFileName = isSupportedSourceFileName;
+    /**
+     * Extension boundaries by priority. Lower numbers indicate higher priorities, and are
+     * aligned to the offset of the highest priority extension in the
+     * allSupportedExtensions array.
+     */
+    var ExtensionPriority;
+    (function (ExtensionPriority) {
+        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
+        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
+        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
+        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
+    })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {}));
+    function getExtensionPriority(path, supportedExtensions) {
+        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
+            if (fileExtensionIs(path, supportedExtensions[i])) {
+                return adjustExtensionPriority(i, supportedExtensions);
+            }
+        }
+        // If its not in the list of supported extensions, this is likely a
+        // TypeScript file with a non-ts extension
+        return 0 /* Highest */;
+    }
+    ts.getExtensionPriority = getExtensionPriority;
+    /**
+     * Adjusts an extension priority to be the highest priority within the same range.
+     */
+    function adjustExtensionPriority(extensionPriority, supportedExtensions) {
+        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
+            return 0 /* TypeScriptFiles */;
+        }
+        else if (extensionPriority < supportedExtensions.length) {
+            return 2 /* DeclarationAndJavaScriptFiles */;
+        }
+        else {
+            return supportedExtensions.length;
+        }
+    }
+    ts.adjustExtensionPriority = adjustExtensionPriority;
+    /**
+     * Gets the next lowest extension priority for a given priority.
+     */
+    function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) {
+        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
+            return 2 /* DeclarationAndJavaScriptFiles */;
+        }
+        else {
+            return supportedExtensions.length;
+        }
+    }
+    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
+    var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */];
+    function removeFileExtension(path) {
+        for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) {
+            var ext = extensionsToRemove_1[_i];
+            var extensionless = tryRemoveExtension(path, ext);
+            if (extensionless !== undefined) {
+                return extensionless;
+            }
+        }
+        return path;
+    }
+    ts.removeFileExtension = removeFileExtension;
+    function tryRemoveExtension(path, extension) {
+        return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
+    }
+    ts.tryRemoveExtension = tryRemoveExtension;
+    function removeExtension(path, extension) {
+        return path.substring(0, path.length - extension.length);
+    }
+    ts.removeExtension = removeExtension;
+    function changeExtension(path, newExtension) {
+        return (removeFileExtension(path) + newExtension);
+    }
+    ts.changeExtension = changeExtension;
+    function Symbol(flags, name) {
+        this.flags = flags;
+        this.escapedName = name;
+        this.declarations = undefined;
+    }
+    function Type(checker, flags) {
+        this.flags = flags;
+        if (Debug.isDebugging) {
+            this.checker = checker;
+        }
+    }
+    function Signature() {
+    }
+    function Node(kind, pos, end) {
+        this.id = 0;
+        this.kind = kind;
+        this.pos = pos;
+        this.end = end;
+        this.flags = 0 /* None */;
+        this.modifierFlagsCache = 0 /* None */;
+        this.transformFlags = 0 /* None */;
+        this.parent = undefined;
+        this.original = undefined;
+    }
+    function SourceMapSource(fileName, text, skipTrivia) {
+        this.fileName = fileName;
+        this.text = text;
+        this.skipTrivia = skipTrivia || (function (pos) { return pos; });
+    }
+    ts.objectAllocator = {
+        getNodeConstructor: function () { return Node; },
+        getTokenConstructor: function () { return Node; },
+        getIdentifierConstructor: function () { return Node; },
+        getSourceFileConstructor: function () { return Node; },
+        getSymbolConstructor: function () { return Symbol; },
+        getTypeConstructor: function () { return Type; },
+        getSignatureConstructor: function () { return Signature; },
+        getSourceMapSourceConstructor: function () { return SourceMapSource; },
+    };
+    var AssertionLevel;
+    (function (AssertionLevel) {
+        AssertionLevel[AssertionLevel["None"] = 0] = "None";
+        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
+        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
+        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
+    })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {}));
+    var Debug;
+    (function (Debug) {
+        Debug.currentAssertionLevel = 0 /* None */;
+        Debug.isDebugging = false;
+        function shouldAssert(level) {
+            return Debug.currentAssertionLevel >= level;
+        }
+        Debug.shouldAssert = shouldAssert;
+        function assert(expression, message, verboseDebugInfo, stackCrawlMark) {
+            if (!expression) {
+                if (verboseDebugInfo) {
+                    message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
+                }
+                fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
+            }
+        }
+        Debug.assert = assert;
+        function assertEqual(a, b, msg, msg2) {
+            if (a !== b) {
+                var message = msg ? msg2 ? msg + " " + msg2 : msg : "";
+                fail("Expected " + a + " === " + b + ". " + message);
+            }
+        }
+        Debug.assertEqual = assertEqual;
+        function assertLessThan(a, b, msg) {
+            if (a >= b) {
+                fail("Expected " + a + " < " + b + ". " + (msg || ""));
+            }
+        }
+        Debug.assertLessThan = assertLessThan;
+        function assertLessThanOrEqual(a, b) {
+            if (a > b) {
+                fail("Expected " + a + " <= " + b);
+            }
+        }
+        Debug.assertLessThanOrEqual = assertLessThanOrEqual;
+        function assertGreaterThanOrEqual(a, b) {
+            if (a < b) {
+                fail("Expected " + a + " >= " + b);
+            }
+        }
+        Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
+        function fail(message, stackCrawlMark) {
+            debugger;
+            var e = new Error(message ? "Debug Failure. " + message : "Debug Failure.");
+            if (Error.captureStackTrace) {
+                Error.captureStackTrace(e, stackCrawlMark || fail);
+            }
+            throw e;
+        }
+        Debug.fail = fail;
+        function assertNever(member, message, stackCrawlMark) {
+            return fail(message || "Illegal value: " + member, stackCrawlMark || assertNever);
+        }
+        Debug.assertNever = assertNever;
+        function getFunctionName(func) {
+            if (typeof func !== "function") {
+                return "";
+            }
+            else if (func.hasOwnProperty("name")) {
+                return func.name;
+            }
+            else {
+                var text = Function.prototype.toString.call(func);
+                var match = /^function\s+([\w\$]+)\s*\(/.exec(text);
+                return match ? match[1] : "";
+            }
+        }
+        Debug.getFunctionName = getFunctionName;
+    })(Debug = ts.Debug || (ts.Debug = {}));
+    /** Remove an item from an array, moving everything to its right one space left. */
+    function orderedRemoveItem(array, item) {
+        for (var i = 0; i < array.length; i++) {
+            if (array[i] === item) {
+                orderedRemoveItemAt(array, i);
+                return true;
+            }
+        }
+        return false;
+    }
+    ts.orderedRemoveItem = orderedRemoveItem;
+    /** Remove an item by index from an array, moving everything to its right one space left. */
+    function orderedRemoveItemAt(array, index) {
+        // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
+        for (var i = index; i < array.length - 1; i++) {
+            array[i] = array[i + 1];
+        }
+        array.pop();
+    }
+    ts.orderedRemoveItemAt = orderedRemoveItemAt;
+    function unorderedRemoveItemAt(array, index) {
+        // Fill in the "hole" left at `index`.
+        array[index] = array[array.length - 1];
+        array.pop();
+    }
+    ts.unorderedRemoveItemAt = unorderedRemoveItemAt;
+    /** Remove the *first* occurrence of `item` from the array. */
+    function unorderedRemoveItem(array, item) {
+        unorderedRemoveFirstItemWhere(array, function (element) { return element === item; });
+    }
+    ts.unorderedRemoveItem = unorderedRemoveItem;
+    /** Remove the *first* element satisfying `predicate`. */
+    function unorderedRemoveFirstItemWhere(array, predicate) {
+        for (var i = 0; i < array.length; i++) {
+            if (predicate(array[i])) {
+                unorderedRemoveItemAt(array, i);
+                break;
+            }
+        }
+    }
+    function createGetCanonicalFileName(useCaseSensitiveFileNames) {
+        return useCaseSensitiveFileNames
+            ? (function (fileName) { return fileName; })
+            : (function (fileName) { return fileName.toLowerCase(); });
+    }
+    ts.createGetCanonicalFileName = createGetCanonicalFileName;
+    /**
+     * patternStrings contains both pattern strings (containing "*") and regular strings.
+     * Return an exact match if possible, or a pattern match, or undefined.
+     * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
+     */
+    function matchPatternOrExact(patternStrings, candidate) {
+        var patterns = [];
+        for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) {
+            var patternString = patternStrings_1[_i];
+            var pattern = tryParsePattern(patternString);
+            if (pattern) {
+                patterns.push(pattern);
+            }
+            else if (patternString === candidate) {
+                // pattern was matched as is - no need to search further
+                return patternString;
+            }
+        }
+        return findBestPatternMatch(patterns, function (_) { return _; }, candidate);
+    }
+    ts.matchPatternOrExact = matchPatternOrExact;
+    function patternText(_a) {
+        var prefix = _a.prefix, suffix = _a.suffix;
+        return prefix + "*" + suffix;
+    }
+    ts.patternText = patternText;
+    /**
+     * Given that candidate matches pattern, returns the text matching the '*'.
+     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
+     */
+    function matchedText(pattern, candidate) {
+        Debug.assert(isPatternMatch(pattern, candidate));
+        return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
+    }
+    ts.matchedText = matchedText;
+    /** Return the object corresponding to the best pattern to match `candidate`. */
+    function findBestPatternMatch(values, getPattern, candidate) {
+        var matchedValue = undefined;
+        // use length of prefix as betterness criteria
+        var longestMatchPrefixLength = -1;
+        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
+            var v = values_1[_i];
+            var pattern = getPattern(v);
+            if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
+                longestMatchPrefixLength = pattern.prefix.length;
+                matchedValue = v;
+            }
+        }
+        return matchedValue;
+    }
+    ts.findBestPatternMatch = findBestPatternMatch;
+    function isPatternMatch(_a, candidate) {
+        var prefix = _a.prefix, suffix = _a.suffix;
+        return candidate.length >= prefix.length + suffix.length &&
+            startsWith(candidate, prefix) &&
+            endsWith(candidate, suffix);
+    }
+    function tryParsePattern(pattern) {
+        // This should be verified outside of here and a proper error thrown.
+        Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
+        var indexOfStar = pattern.indexOf("*");
+        return indexOfStar === -1 ? undefined : {
+            prefix: pattern.substr(0, indexOfStar),
+            suffix: pattern.substr(indexOfStar + 1)
+        };
+    }
+    ts.tryParsePattern = tryParsePattern;
+    function positionIsSynthesized(pos) {
+        // This is a fast way of testing the following conditions:
+        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
+        return !(pos >= 0);
+    }
+    ts.positionIsSynthesized = positionIsSynthesized;
+    /** True if an extension is one of the supported TypeScript extensions. */
+    function extensionIsTypeScript(ext) {
+        return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */;
+    }
+    ts.extensionIsTypeScript = extensionIsTypeScript;
+    /**
+     * Gets the extension from a path.
+     * Path must have a valid extension.
+     */
+    function extensionFromPath(path) {
+        var ext = tryGetExtensionFromPath(path);
+        if (ext !== undefined) {
+            return ext;
+        }
+        Debug.fail("File " + path + " has unknown extension.");
+    }
+    ts.extensionFromPath = extensionFromPath;
+    function isAnySupportedFileExtension(path) {
+        return tryGetExtensionFromPath(path) !== undefined;
+    }
+    ts.isAnySupportedFileExtension = isAnySupportedFileExtension;
+    function tryGetExtensionFromPath(path) {
+        return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); });
+    }
+    ts.tryGetExtensionFromPath = tryGetExtensionFromPath;
+    // Retrieves any string from the final "." onwards from a base file name.
+    // Unlike extensionFromPath, which throws an exception on unrecognized extensions.
+    function getAnyExtensionFromPath(path) {
+        var baseFileName = getBaseFileName(path);
+        var extensionIndex = baseFileName.lastIndexOf(".");
+        if (extensionIndex >= 0) {
+            return baseFileName.substring(extensionIndex);
+        }
+    }
+    ts.getAnyExtensionFromPath = getAnyExtensionFromPath;
+    function isCheckJsEnabledForFile(sourceFile, compilerOptions) {
+        return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
+    }
+    ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile;
+    function and(f, g) {
+        return function (arg) { return f(arg) && g(arg); };
+    }
+    ts.and = and;
+    function assertTypeIsNever(_) { }
+    ts.assertTypeIsNever = assertTypeIsNever;
+    function createCachedDirectoryStructureHost(host) {
+        var cachedReadDirectoryResult = createMap();
+        var getCurrentDirectory = memoize(function () { return host.getCurrentDirectory(); });
+        var getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
+        return {
+            useCaseSensitiveFileNames: host.useCaseSensitiveFileNames,
+            newLine: host.newLine,
+            readFile: function (path, encoding) { return host.readFile(path, encoding); },
+            write: function (s) { return host.write(s); },
+            writeFile: writeFile,
+            fileExists: fileExists,
+            directoryExists: directoryExists,
+            createDirectory: createDirectory,
+            getCurrentDirectory: getCurrentDirectory,
+            getDirectories: getDirectories,
+            readDirectory: readDirectory,
+            addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory,
+            addOrDeleteFile: addOrDeleteFile,
+            clearCache: clearCache,
+            exit: function (code) { return host.exit(code); }
+        };
+        function toPath(fileName) {
+            return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName);
+        }
+        function getCachedFileSystemEntries(rootDirPath) {
+            return cachedReadDirectoryResult.get(rootDirPath);
+        }
+        function getCachedFileSystemEntriesForBaseDir(path) {
+            return getCachedFileSystemEntries(getDirectoryPath(path));
+        }
+        function getBaseNameOfFileName(fileName) {
+            return getBaseFileName(normalizePath(fileName));
+        }
+        function createCachedFileSystemEntries(rootDir, rootDirPath) {
+            var resultFromHost = {
+                files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [],
+                directories: host.getDirectories(rootDir) || []
+            };
+            cachedReadDirectoryResult.set(rootDirPath, resultFromHost);
+            return resultFromHost;
+        }
+        /**
+         * If the readDirectory result was already cached, it returns that
+         * Otherwise gets result from host and caches it.
+         * The host request is done under try catch block to avoid caching incorrect result
+         */
+        function tryReadDirectory(rootDir, rootDirPath) {
+            var cachedResult = getCachedFileSystemEntries(rootDirPath);
+            if (cachedResult) {
+                return cachedResult;
+            }
+            try {
+                return createCachedFileSystemEntries(rootDir, rootDirPath);
+            }
+            catch (_e) {
+                // If there is exception to read directories, dont cache the result and direct the calls to host
+                Debug.assert(!cachedReadDirectoryResult.has(rootDirPath));
+                return undefined;
+            }
+        }
+        function fileNameEqual(name1, name2) {
+            return getCanonicalFileName(name1) === getCanonicalFileName(name2);
+        }
+        function hasEntry(entries, name) {
+            return some(entries, function (file) { return fileNameEqual(file, name); });
+        }
+        function updateFileSystemEntry(entries, baseName, isValid) {
+            if (hasEntry(entries, baseName)) {
+                if (!isValid) {
+                    return filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); });
+                }
+            }
+            else if (isValid) {
+                return entries.push(baseName);
+            }
+        }
+        function writeFile(fileName, data, writeByteOrderMark) {
+            var path = toPath(fileName);
+            var result = getCachedFileSystemEntriesForBaseDir(path);
+            if (result) {
+                updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
+            }
+            return host.writeFile(fileName, data, writeByteOrderMark);
+        }
+        function fileExists(fileName) {
+            var path = toPath(fileName);
+            var result = getCachedFileSystemEntriesForBaseDir(path);
+            return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
+                host.fileExists(fileName);
+        }
+        function directoryExists(dirPath) {
+            var path = toPath(dirPath);
+            return cachedReadDirectoryResult.has(path) || host.directoryExists(dirPath);
+        }
+        function createDirectory(dirPath) {
+            var path = toPath(dirPath);
+            var result = getCachedFileSystemEntriesForBaseDir(path);
+            var baseFileName = getBaseNameOfFileName(dirPath);
+            if (result) {
+                updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
+            }
+            host.createDirectory(dirPath);
+        }
+        function getDirectories(rootDir) {
+            var rootDirPath = toPath(rootDir);
+            var result = tryReadDirectory(rootDir, rootDirPath);
+            if (result) {
+                return result.directories.slice();
+            }
+            return host.getDirectories(rootDir);
+        }
+        function readDirectory(rootDir, extensions, excludes, includes, depth) {
+            var rootDirPath = toPath(rootDir);
+            var result = tryReadDirectory(rootDir, rootDirPath);
+            if (result) {
+                return matchFiles(rootDir, extensions, excludes, includes, host.useCaseSensitiveFileNames, getCurrentDirectory(), depth, getFileSystemEntries);
+            }
+            return host.readDirectory(rootDir, extensions, excludes, includes, depth);
+            function getFileSystemEntries(dir) {
+                var path = toPath(dir);
+                if (path === rootDirPath) {
+                    return result;
+                }
+                return getCachedFileSystemEntries(path) || createCachedFileSystemEntries(dir, path);
+            }
+        }
+        function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
+            var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
+            if (existingResult) {
+                // This was a folder already present, remove it if this doesnt exist any more
+                if (!host.directoryExists(fileOrDirectory)) {
+                    cachedReadDirectoryResult.delete(fileOrDirectoryPath);
+                }
+            }
+            else {
+                // This was earlier a file (hence not in cached directory contents)
+                // or we never cached the directory containing it
+                var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
+                if (parentResult) {
+                    var baseName = getBaseNameOfFileName(fileOrDirectory);
+                    if (parentResult) {
+                        var fsQueryResult = {
+                            fileExists: host.fileExists(fileOrDirectoryPath),
+                            directoryExists: host.directoryExists(fileOrDirectoryPath)
+                        };
+                        updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
+                        updateFileSystemEntry(parentResult.directories, baseName, fsQueryResult.directoryExists);
+                        return fsQueryResult;
+                    }
+                }
+            }
+        }
+        function addOrDeleteFile(fileName, filePath, eventKind) {
+            if (eventKind === ts.FileWatcherEventKind.Changed) {
+                return;
+            }
+            var parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
+            if (parentResult) {
+                updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created);
+            }
+        }
+        function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) {
+            updateFileSystemEntry(parentResult.files, baseName, fileExists);
+        }
+        function clearCache() {
+            cachedReadDirectoryResult.clear();
+        }
+    }
+    ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost;
+})(ts || (ts = {}));
+/// <reference path="core.ts"/>
+var ts;
+(function (ts) {
+    /**
+     * Set a high stack trace limit to provide more information in case of an error.
+     * Called for command-line and server use cases.
+     * Not called if TypeScript is used as a library.
+     */
+    /* @internal */
+    function setStackTraceLimit() {
+        if (Error.stackTraceLimit < 100) {
+            Error.stackTraceLimit = 100;
+        }
+    }
+    ts.setStackTraceLimit = setStackTraceLimit;
+    var FileWatcherEventKind;
+    (function (FileWatcherEventKind) {
+        FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created";
+        FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed";
+        FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted";
+    })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {}));
+    function getNodeMajorVersion() {
+        if (typeof process === "undefined") {
+            return undefined;
+        }
+        var version = process.version;
+        if (!version) {
+            return undefined;
+        }
+        var dot = version.indexOf(".");
+        if (dot === -1) {
+            return undefined;
+        }
+        return parseInt(version.substring(1, dot));
+    }
+    ts.getNodeMajorVersion = getNodeMajorVersion;
+    ts.sys = (function () {
+        function getNodeSystem() {
+            var _fs = require("fs");
+            var _path = require("path");
+            var _os = require("os");
+            var _crypto = require("crypto");
+            var useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER;
+            function createWatchedFileSet() {
+                var dirWatchers = ts.createMap();
+                // One file can have multiple watchers
+                var fileWatcherCallbacks = ts.createMultiMap();
+                return { addFile: addFile, removeFile: removeFile };
+                function reduceDirWatcherRefCountForFile(fileName) {
+                    var dirName = ts.getDirectoryPath(fileName);
+                    var watcher = dirWatchers.get(dirName);
+                    if (watcher) {
+                        watcher.referenceCount -= 1;
+                        if (watcher.referenceCount <= 0) {
+                            watcher.close();
+                            dirWatchers.delete(dirName);
+                        }
+                    }
+                }
+                function addDirWatcher(dirPath) {
+                    var watcher = dirWatchers.get(dirPath);
+                    if (watcher) {
+                        watcher.referenceCount += 1;
+                        return;
+                    }
+                    watcher = fsWatchDirectory(dirPath || ".", function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); });
+                    watcher.referenceCount = 1;
+                    dirWatchers.set(dirPath, watcher);
+                    return;
+                }
+                function addFileWatcherCallback(filePath, callback) {
+                    fileWatcherCallbacks.add(filePath, callback);
+                }
+                function addFile(fileName, callback) {
+                    addFileWatcherCallback(fileName, callback);
+                    addDirWatcher(ts.getDirectoryPath(fileName));
+                    return { fileName: fileName, callback: callback };
+                }
+                function removeFile(watchedFile) {
+                    removeFileWatcherCallback(watchedFile.fileName, watchedFile.callback);
+                    reduceDirWatcherRefCountForFile(watchedFile.fileName);
+                }
+                function removeFileWatcherCallback(filePath, callback) {
+                    fileWatcherCallbacks.remove(filePath, callback);
+                }
+                function fileEventHandler(eventName, relativeFileName, baseDirPath) {
+                    // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
+                    var fileName = !ts.isString(relativeFileName)
+                        ? undefined
+                        : ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
+                    // Some applications save a working file via rename operations
+                    if ((eventName === "change" || eventName === "rename")) {
+                        var callbacks = fileWatcherCallbacks.get(fileName);
+                        if (callbacks) {
+                            for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
+                                var fileCallback = callbacks_1[_i];
+                                fileCallback(fileName, FileWatcherEventKind.Changed);
+                            }
+                        }
+                    }
+                }
+            }
+            var watchedFileSet = createWatchedFileSet();
+            var nodeVersion = getNodeMajorVersion();
+            var isNode4OrLater = nodeVersion >= 4;
+            function isFileSystemCaseSensitive() {
+                // win32\win64 are case insensitive platforms
+                if (platform === "win32" || platform === "win64") {
+                    return false;
+                }
+                // If this file exists under a different case, we must be case-insensitve.
+                return !fileExists(swapCase(__filename));
+            }
+            /** Convert all lowercase chars to uppercase, and vice-versa */
+            function swapCase(s) {
+                return s.replace(/\w/g, function (ch) {
+                    var up = ch.toUpperCase();
+                    return ch === up ? ch.toLowerCase() : up;
+                });
+            }
+            var platform = _os.platform();
+            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
+            function fsWatchFile(fileName, callback, pollingInterval) {
+                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval || 250 }, fileChanged);
+                return {
+                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
+                };
+                function fileChanged(curr, prev) {
+                    var isCurrZero = +curr.mtime === 0;
+                    var isPrevZero = +prev.mtime === 0;
+                    var created = !isCurrZero && isPrevZero;
+                    var deleted = isCurrZero && !isPrevZero;
+                    var eventKind = created
+                        ? FileWatcherEventKind.Created
+                        : deleted
+                            ? FileWatcherEventKind.Deleted
+                            : FileWatcherEventKind.Changed;
+                    if (eventKind === FileWatcherEventKind.Changed && +curr.mtime <= +prev.mtime) {
+                        return;
+                    }
+                    callback(fileName, eventKind);
+                }
+            }
+            function fsWatchDirectory(directoryName, callback, recursive) {
+                var options;
+                /** Watcher for the directory depending on whether it is missing or present */
+                var watcher = !directoryExists(directoryName) ?
+                    watchMissingDirectory() :
+                    watchPresentDirectory();
+                return {
+                    close: function () {
+                        // Close the watcher (either existing directory watcher or missing directory watcher)
+                        watcher.close();
+                    }
+                };
+                /**
+                 * Watch the directory that is currently present
+                 * and when the watched directory is deleted, switch to missing directory watcher
+                 */
+                function watchPresentDirectory() {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    if (options === undefined) {
+                        if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) {
+                            options = { persistent: true, recursive: !!recursive };
+                        }
+                        else {
+                            options = { persistent: true };
+                        }
+                    }
+                    var dirWatcher = _fs.watch(directoryName, options, callback);
+                    dirWatcher.on("error", function () {
+                        if (!directoryExists(directoryName)) {
+                            // Deleting directory
+                            watcher = watchMissingDirectory();
+                            // Call the callback for current directory
+                            callback("rename", "");
+                        }
+                    });
+                    return dirWatcher;
+                }
+                /**
+                 * Watch the directory that is missing
+                 * and switch to existing directory when the directory is created
+                 */
+                function watchMissingDirectory() {
+                    return fsWatchFile(directoryName, function (_fileName, eventKind) {
+                        if (eventKind === FileWatcherEventKind.Created && directoryExists(directoryName)) {
+                            watcher.close();
+                            watcher = watchPresentDirectory();
+                            // Call the callback for current directory
+                            // For now it could be callback for the inner directory creation,
+                            // but just return current directory, better than current no-op
+                            callback("rename", "");
+                        }
+                    });
+                }
+            }
+            function readFile(fileName, _encoding) {
+                if (!fileExists(fileName)) {
+                    return undefined;
+                }
+                var buffer = _fs.readFileSync(fileName);
+                var len = buffer.length;
+                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
+                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
+                    // flip all byte pairs and treat as little endian.
+                    len &= ~1; // Round down to a multiple of 2
+                    for (var i = 0; i < len; i += 2) {
+                        var temp = buffer[i];
+                        buffer[i] = buffer[i + 1];
+                        buffer[i + 1] = temp;
+                    }
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
+                    // Little endian UTF-16 byte order mark detected
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
+                    // UTF-8 byte order mark detected
+                    return buffer.toString("utf8", 3);
+                }
+                // Default is UTF-8 with no byte order mark
+                return buffer.toString("utf8");
+            }
+            function writeFile(fileName, data, writeByteOrderMark) {
+                // If a BOM is required, emit one
+                if (writeByteOrderMark) {
+                    data = "\uFEFF" + data;
+                }
+                var fd;
+                try {
+                    fd = _fs.openSync(fileName, "w");
+                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
+                }
+                finally {
+                    if (fd !== undefined) {
+                        _fs.closeSync(fd);
+                    }
+                }
+            }
+            function getAccessibleFileSystemEntries(path) {
+                try {
+                    var entries = _fs.readdirSync(path || ".").sort();
+                    var files = [];
+                    var directories = [];
+                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                        var entry = entries_1[_i];
+                        // This is necessary because on some file system node fails to exclude
+                        // "." and "..". See https://github.com/nodejs/node/issues/4002
+                        if (entry === "." || entry === "..") {
+                            continue;
+                        }
+                        var name = ts.combinePaths(path, entry);
+                        var stat = void 0;
+                        try {
+                            stat = _fs.statSync(name);
+                        }
+                        catch (e) {
+                            continue;
+                        }
+                        if (stat.isFile()) {
+                            files.push(entry);
+                        }
+                        else if (stat.isDirectory()) {
+                            directories.push(entry);
+                        }
+                    }
+                    return { files: files, directories: directories };
+                }
+                catch (e) {
+                    return { files: [], directories: [] };
+                }
+            }
+            function readDirectory(path, extensions, excludes, includes, depth) {
+                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries);
+            }
+            var FileSystemEntryKind;
+            (function (FileSystemEntryKind) {
+                FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File";
+                FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory";
+            })(FileSystemEntryKind || (FileSystemEntryKind = {}));
+            function fileSystemEntryExists(path, entryKind) {
+                try {
+                    var stat = _fs.statSync(path);
+                    switch (entryKind) {
+                        case 0 /* File */: return stat.isFile();
+                        case 1 /* Directory */: return stat.isDirectory();
+                    }
+                }
+                catch (e) {
+                    return false;
+                }
+            }
+            function fileExists(path) {
+                return fileSystemEntryExists(path, 0 /* File */);
+            }
+            function directoryExists(path) {
+                return fileSystemEntryExists(path, 1 /* Directory */);
+            }
+            function getDirectories(path) {
+                return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); });
+            }
+            var nodeSystem = {
+                args: process.argv.slice(2),
+                newLine: _os.EOL,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                write: function (s) {
+                    process.stdout.write(s);
+                },
+                readFile: readFile,
+                writeFile: writeFile,
+                watchFile: function (fileName, callback, pollingInterval) {
+                    if (useNonPollingWatchers) {
+                        var watchedFile_1 = watchedFileSet.addFile(fileName, callback);
+                        return {
+                            close: function () { return watchedFileSet.removeFile(watchedFile_1); }
+                        };
+                    }
+                    else {
+                        return fsWatchFile(fileName, callback, pollingInterval);
+                    }
+                },
+                watchDirectory: function (directoryName, callback, recursive) {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    return fsWatchDirectory(directoryName, function (eventName, relativeFileName) {
+                        // In watchDirectory we only care about adding and removing files (when event name is
+                        // "rename"); changes made within files are handled by corresponding fileWatchers (when
+                        // event name is "change")
+                        if (eventName === "rename") {
+                            // When deleting a file, the passed baseFileName is null
+                            callback(!relativeFileName ? relativeFileName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)));
+                        }
+                    }, recursive);
+                },
+                resolvePath: function (path) { return _path.resolve(path); },
+                fileExists: fileExists,
+                directoryExists: directoryExists,
+                createDirectory: function (directoryName) {
+                    if (!nodeSystem.directoryExists(directoryName)) {
+                        _fs.mkdirSync(directoryName);
+                    }
+                },
+                getExecutingFilePath: function () {
+                    return __filename;
+                },
+                getCurrentDirectory: function () {
+                    return process.cwd();
+                },
+                getDirectories: getDirectories,
+                getEnvironmentVariable: function (name) {
+                    return process.env[name] || "";
+                },
+                readDirectory: readDirectory,
+                getModifiedTime: function (path) {
+                    try {
+                        return _fs.statSync(path).mtime;
+                    }
+                    catch (e) {
+                        return undefined;
+                    }
+                },
+                createHash: function (data) {
+                    var hash = _crypto.createHash("md5");
+                    hash.update(data);
+                    return hash.digest("hex");
+                },
+                getMemoryUsage: function () {
+                    if (global.gc) {
+                        global.gc();
+                    }
+                    return process.memoryUsage().heapUsed;
+                },
+                getFileSize: function (path) {
+                    try {
+                        var stat = _fs.statSync(path);
+                        if (stat.isFile()) {
+                            return stat.size;
+                        }
+                    }
+                    catch (e) { }
+                    return 0;
+                },
+                exit: function (exitCode) {
+                    process.exit(exitCode);
+                },
+                realpath: function (path) {
+                    return _fs.realpathSync(path);
+                },
+                debugMode: ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
+                tryEnableSourceMapsForHost: function () {
+                    try {
+                        require("source-map-support").install();
+                    }
+                    catch (e) {
+                        // Could not enable source maps.
+                    }
+                },
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout
+            };
+            return nodeSystem;
+        }
+        function getChakraSystem() {
+            var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); });
+            return {
+                newLine: ChakraHost.newLine || "\r\n",
+                args: ChakraHost.args,
+                useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
+                write: ChakraHost.echo,
+                readFile: function (path, _encoding) {
+                    // encoding is automatically handled by the implementation in ChakraHost
+                    return ChakraHost.readFile(path);
+                },
+                writeFile: function (path, data, writeByteOrderMark) {
+                    // If a BOM is required, emit one
+                    if (writeByteOrderMark) {
+                        data = "\uFEFF" + data;
+                    }
+                    ChakraHost.writeFile(path, data);
+                },
+                resolvePath: ChakraHost.resolvePath,
+                fileExists: ChakraHost.fileExists,
+                directoryExists: ChakraHost.directoryExists,
+                createDirectory: ChakraHost.createDirectory,
+                getExecutingFilePath: function () { return ChakraHost.executingFile; },
+                getCurrentDirectory: function () { return ChakraHost.currentDirectory; },
+                getDirectories: ChakraHost.getDirectories,
+                getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (function () { return ""; }),
+                readDirectory: function (path, extensions, excludes, includes, _depth) {
+                    var pattern = ts.getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
+                    return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
+                },
+                exit: ChakraHost.quit,
+                realpath: realpath
+            };
+        }
+        function recursiveCreateDirectory(directoryPath, sys) {
+            var basePath = ts.getDirectoryPath(directoryPath);
+            var shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
+            if (shouldCreateParent) {
+                recursiveCreateDirectory(basePath, sys);
+            }
+            if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
+                sys.createDirectory(directoryPath);
+            }
+        }
+        var sys;
+        if (typeof ChakraHost !== "undefined") {
+            sys = getChakraSystem();
+        }
+        else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
+            // process and process.nextTick checks if current environment is node-like
+            // process.browser check excludes webpack and browserify
+            sys = getNodeSystem();
+        }
+        if (sys) {
+            // patch writefile to create folder before writing the file
+            var originalWriteFile_1 = sys.writeFile;
+            sys.writeFile = function (path, data, writeBom) {
+                var directoryPath = ts.getDirectoryPath(ts.normalizeSlashes(path));
+                if (directoryPath && !sys.directoryExists(directoryPath)) {
+                    recursiveCreateDirectory(directoryPath, sys);
+                }
+                originalWriteFile_1.call(sys, path, data, writeBom);
+            };
+        }
+        return sys;
+    })();
+    if (ts.sys && ts.sys.getEnvironmentVariable) {
+        ts.Debug.currentAssertionLevel = /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))
+            ? 1 /* Normal */
+            : 0 /* None */;
+    }
+    if (ts.sys && ts.sys.debugMode) {
+        ts.Debug.isDebugging = true;
+    }
+})(ts || (ts = {}));
+// <auto-generated />
+/// <reference path="types.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    function diag(code, category, key, message) {
+        return { code: code, category: category, key: key, message: message };
+    }
+    ts.Diagnostics = {
+        Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."),
+        Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."),
+        _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."),
+        A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."),
+        Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."),
+        Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."),
+        Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."),
+        A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."),
+        Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."),
+        A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."),
+        An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."),
+        An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."),
+        An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."),
+        An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."),
+        An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."),
+        An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."),
+        An_index_signature_parameter_type_must_be_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_string_or_number_1023", "An index signature parameter type must be 'string' or 'number'."),
+        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."),
+        Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."),
+        _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."),
+        _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."),
+        _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."),
+        super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."),
+        Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."),
+        Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."),
+        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."),
+        Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."),
+        _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."),
+        _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."),
+        _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."),
+        _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."),
+        _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."),
+        A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."),
+        A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: diag(1046, ts.DiagnosticCategory.Error, "A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046", "A 'declare' modifier is required for a top level declaration in a .d.ts file."),
+        A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."),
+        A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."),
+        A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."),
+        A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."),
+        A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."),
+        A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."),
+        A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."),
+        Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."),
+        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."),
+        An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."),
+        The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."),
+        A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."),
+        The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."),
+        Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."),
+        Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."),
+        An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."),
+        The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise<T> type."),
+        In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."),
+        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."),
+        _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."),
+        _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."),
+        A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."),
+        Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."),
+        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."),
+        An_accessor_cannot_be_declared_in_an_ambient_context: diag(1086, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_declared_in_an_ambient_context_1086", "An accessor cannot be declared in an ambient context."),
+        _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."),
+        _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."),
+        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."),
+        Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."),
+        Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."),
+        An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."),
+        A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."),
+        An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."),
+        _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."),
+        Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."),
+        Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."),
+        Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."),
+        with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."),
+        delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."),
+        A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."),
+        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."),
+        A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."),
+        Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."),
+        A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."),
+        Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."),
+        Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."),
+        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."),
+        Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."),
+        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."),
+        A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."),
+        An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."),
+        An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."),
+        An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."),
+        An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."),
+        Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."),
+        A_tuple_type_element_list_cannot_be_empty: diag(1122, ts.DiagnosticCategory.Error, "A_tuple_type_element_list_cannot_be_empty_1122", "A tuple type element list cannot be empty."),
+        Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."),
+        Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."),
+        Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."),
+        Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."),
+        Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."),
+        Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."),
+        Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."),
+        case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."),
+        Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."),
+        Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."),
+        Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."),
+        Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."),
+        Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."),
+        Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."),
+        Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."),
+        Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."),
+        Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."),
+        String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."),
+        Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."),
+        or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."),
+        Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."),
+        Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."),
+        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."),
+        File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."),
+        new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: diag(1150, ts.DiagnosticCategory.Error, "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead."),
+        const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."),
+        const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."),
+        let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."),
+        Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."),
+        Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."),
+        An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."),
+        A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."),
+        Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."),
+        A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol_1165", "A computed property name in an ambient context must directly refer to a built-in symbol."),
+        A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol_1166", "A computed property name in a class property declaration must directly refer to a built-in symbol."),
+        A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol_1168", "A computed property name in a method overload must directly refer to a built-in symbol."),
+        A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol_1169", "A computed property name in an interface must directly refer to a built-in symbol."),
+        A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol_1170", "A computed property name in a type literal must directly refer to a built-in symbol."),
+        A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."),
+        extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."),
+        extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."),
+        Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."),
+        implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."),
+        Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."),
+        Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."),
+        Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."),
+        Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."),
+        Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."),
+        Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."),
+        A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."),
+        An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."),
+        Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."),
+        Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."),
+        A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."),
+        A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."),
+        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."),
+        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."),
+        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."),
+        An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."),
+        Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."),
+        An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."),
+        Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."),
+        Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."),
+        Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."),
+        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."),
+        Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."),
+        Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."),
+        Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."),
+        Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."),
+        Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided: diag(1205, ts.DiagnosticCategory.Error, "Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205", "Cannot re-export a type when the '--isolatedModules' flag is provided."),
+        Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."),
+        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."),
+        Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided_1208", "Cannot compile namespaces when the '--isolatedModules' flag is provided."),
+        Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: diag(1209, ts.DiagnosticCategory.Error, "Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided_1209", "Ambient const enums are not allowed when the '--isolatedModules' flag is provided."),
+        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."),
+        A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."),
+        Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."),
+        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."),
+        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."),
+        Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."),
+        Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."),
+        Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."),
+        Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning."),
+        Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."),
+        Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."),
+        An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."),
+        _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."),
+        Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."),
+        Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."),
+        Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."),
+        Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."),
+        A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."),
+        A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."),
+        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."),
+        An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."),
+        An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."),
+        An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."),
+        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."),
+        A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."),
+        The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."),
+        The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."),
+        Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."),
+        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."),
+        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."),
+        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."),
+        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."),
+        _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."),
+        Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."),
+        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."),
+        An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."),
+        A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."),
+        A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."),
+        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."),
+        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."),
+        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."),
+        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."),
+        _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."),
+        A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254", "A 'const' initializer in an ambient context must be a string or numeric literal."),
+        with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."),
+        await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."),
+        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."),
+        The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."),
+        Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."),
+        Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."),
+        Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."),
+        A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."),
+        An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."),
+        A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."),
+        Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."),
+        Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."),
+        Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."),
+        Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules_1323", "Dynamic import cannot be used when targeting ECMAScript 2015 modules."),
+        Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."),
+        Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."),
+        Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"),
+        String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."),
+        Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."),
+        _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"),
+        Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."),
+        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."),
+        Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."),
+        Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."),
+        Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."),
+        Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."),
+        File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."),
+        Cannot_find_module_0: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_2307", "Cannot find module '{0}'."),
+        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."),
+        An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."),
+        Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."),
+        A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."),
+        An_interface_may_only_extend_a_class_or_another_interface: diag(2312, ts.DiagnosticCategory.Error, "An_interface_may_only_extend_a_class_or_another_interface_2312", "An interface may only extend a class or another interface."),
+        Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."),
+        Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."),
+        Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."),
+        Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."),
+        Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."),
+        Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."),
+        Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."),
+        Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."),
+        Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."),
+        Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."),
+        Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."),
+        Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."),
+        Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."),
+        Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."),
+        Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."),
+        Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."),
+        Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."),
+        Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."),
+        this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."),
+        this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."),
+        this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."),
+        this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."),
+        super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."),
+        super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."),
+        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."),
+        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."),
+        Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."),
+        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."),
+        Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."),
+        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."),
+        This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343", "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'."),
+        Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."),
+        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."),
+        Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."),
+        Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."),
+        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"),
+        Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures: diag(2349, ts.DiagnosticCategory.Error, "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatur_2349", "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures."),
+        Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."),
+        Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: diag(2351, ts.DiagnosticCategory.Error, "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351", "Cannot use 'new' with an expression whose type lacks a call or construct signature."),
+        Type_0_cannot_be_converted_to_type_1: diag(2352, ts.DiagnosticCategory.Error, "Type_0_cannot_be_converted_to_type_1_2352", "Type '{0}' cannot be converted to type '{1}'."),
+        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."),
+        This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."),
+        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."),
+        An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number' or an enum type."),
+        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."),
+        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."),
+        The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."),
+        The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."),
+        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."),
+        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."),
+        The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."),
+        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."),
+        Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
+        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."),
+        Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."),
+        A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."),
+        A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."),
+        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."),
+        Parameter_0_cannot_be_referenced_in_its_initializer: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_be_referenced_in_its_initializer_2372", "Parameter '{0}' cannot be referenced in its initializer."),
+        Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it."),
+        Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."),
+        Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."),
+        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties."),
+        Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."),
+        A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."),
+        Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."),
+        get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."),
+        A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."),
+        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."),
+        Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."),
+        Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."),
+        Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."),
+        Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."),
+        Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."),
+        Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."),
+        Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."),
+        Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."),
+        Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."),
+        Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."),
+        Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."),
+        Overload_signature_is_not_compatible_with_function_implementation: diag(2394, ts.DiagnosticCategory.Error, "Overload_signature_is_not_compatible_with_function_implementation_2394", "Overload signature is not compatible with function implementation."),
+        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."),
+        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."),
+        Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."),
+        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."),
+        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."),
+        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."),
+        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."),
+        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'."),
+        The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."),
+        The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."),
+        The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."),
+        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter."),
+        Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."),
+        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."),
+        The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."),
+        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."),
+        Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."),
+        Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."),
+        Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."),
+        Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."),
+        Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."),
+        Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."),
+        A_class_may_only_implement_another_class_or_interface: diag(2422, ts.DiagnosticCategory.Error, "A_class_may_only_implement_another_class_or_interface_2422", "A class may only implement another class or interface."),
+        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."),
+        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: diag(2424, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property."),
+        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."),
+        Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."),
+        Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."),
+        All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."),
+        Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."),
+        Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."),
+        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."),
+        A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."),
+        A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."),
+        Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."),
+        Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."),
+        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."),
+        Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."),
+        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."),
+        Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."),
+        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."),
+        Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."),
+        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."),
+        Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."),
+        Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."),
+        Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."),
+        The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."),
+        Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."),
+        Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."),
+        Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."),
+        Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."),
+        An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."),
+        The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."),
+        Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."),
+        Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."),
+        Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."),
+        Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."),
+        An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."),
+        Type_0_has_no_property_1_and_no_string_index_signature: diag(2459, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_and_no_string_index_signature_2459", "Type '{0}' has no property '{1}' and no string index signature."),
+        Type_0_has_no_property_1: diag(2460, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_2460", "Type '{0}' has no property '{1}'."),
+        Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."),
+        A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."),
+        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."),
+        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."),
+        this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."),
+        super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."),
+        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."),
+        Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."),
+        The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."),
+        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."),
+        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."),
+        Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."),
+        Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."),
+        In_const_enum_declarations_member_initializer_must_be_constant_expression: diag(2474, ts.DiagnosticCategory.Error, "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474", "In 'const' enum declarations member initializer must be constant expression."),
+        const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment."),
+        A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."),
+        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."),
+        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."),
+        Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."),
+        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."),
+        Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."),
+        The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."),
+        Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."),
+        The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."),
+        Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type must have a '[Symbol.iterator]()' method that returns an iterator."),
+        An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."),
+        The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the 'next()' method of an iterator must have a 'value' property."),
+        The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."),
+        Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."),
+        Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2_2493", "Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'."),
+        Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."),
+        Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."),
+        The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."),
+        Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct: diag(2497, ts.DiagnosticCategory.Error, "Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497", "Module '{0}' resolves to a non-module entity and cannot be imported using this construct."),
+        Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."),
+        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."),
+        A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."),
+        A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."),
+        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."),
+        Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."),
+        Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator."),
+        A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."),
+        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."),
+        Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."),
+        No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."),
+        Base_constructor_return_type_0_is_not_a_class_or_interface_type: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509", "Base constructor return type '{0}' is not a class or interface type."),
+        Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."),
+        Cannot_create_an_instance_of_the_abstract_class_0: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_the_abstract_class_0_2511", "Cannot create an instance of the abstract class '{0}'."),
+        Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."),
+        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."),
+        Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."),
+        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."),
+        All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."),
+        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."),
+        A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."),
+        An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."),
+        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."),
+        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."),
+        The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."),
+        yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."),
+        await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."),
+        Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."),
+        A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."),
+        The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary."),
+        A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."),
+        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."),
+        Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."),
+        Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."),
+        Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."),
+        Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."),
+        A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."),
+        Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."),
+        Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."),
+        Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."),
+        Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."),
+        Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."),
+        Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property_2540", "Cannot assign to '{0}' because it is a constant or a read-only property."),
+        The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."),
+        Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."),
+        Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."),
+        Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."),
+        A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."),
+        Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1: diag(2546, ts.DiagnosticCategory.Error, "Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1_2546", "Property '{0}' has conflicting declarations and is inaccessible in type '{1}'."),
+        The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547", "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property."),
+        Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
+        Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
+        Generic_type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2550, ts.DiagnosticCategory.Error, "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550", "Generic type instantiation is excessively deep and possibly infinite."),
+        Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"),
+        Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"),
+        Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."),
+        Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."),
+        Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."),
+        Expected_0_arguments_but_got_a_minimum_of_1: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_a_minimum_of_1_2556", "Expected {0} arguments, but got a minimum of {1}."),
+        Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."),
+        Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."),
+        Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."),
+        Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"),
+        Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"),
+        Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."),
+        The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."),
+        JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."),
+        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."),
+        JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."),
+        Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."),
+        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."),
+        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."),
+        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."),
+        JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."),
+        The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."),
+        JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."),
+        Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."),
+        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."),
+        Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."),
+        Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."),
+        Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."),
+        Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."),
+        JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."),
+        Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."),
+        super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."),
+        super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."),
+        Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."),
+        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"),
+        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"),
+        Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."),
+        Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."),
+        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."),
+        Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."),
+        export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."),
+        Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."),
+        Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."),
+        Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."),
+        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."),
+        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."),
+        Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."),
+        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."),
+        Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."),
+        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."),
+        Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."),
+        A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."),
+        A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."),
+        A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."),
+        get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."),
+        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."),
+        The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."),
+        The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."),
+        _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."),
+        All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."),
+        Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."),
+        Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"),
+        An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."),
+        _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."),
+        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."),
+        Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."),
+        Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects."),
+        The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"),
+        An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
+        Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."),
+        Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."),
+        Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."),
+        The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."),
+        _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."),
+        The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a delete operator must be a property reference."),
+        The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a delete operator cannot be a read-only property."),
+        An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
+        Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."),
+        Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."),
+        Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."),
+        Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."),
+        _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."),
+        A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
+        A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
+        Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"),
+        The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."),
+        Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."),
+        Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."),
+        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."),
+        Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."),
+        Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
+        Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
+        Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
+        Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."),
+        Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."),
+        Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."),
+        Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."),
+        extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."),
+        extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."),
+        Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."),
+        Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."),
+        Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."),
+        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
+        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
+        Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."),
+        Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
+        Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
+        Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."),
+        Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
+        Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."),
+        Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_4034", "Parameter '{0}' of public static property setter from exported class has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter '{0}' of public static property setter from exported class has or is using private name '{1}'."),
+        Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_4036", "Parameter '{0}' of public property setter from exported class has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter '{0}' of public property setter from exported class has or is using private name '{1}'."),
+        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_externa_4038", "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named."),
+        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_4039", "Return type of public static property getter from exported class has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0_4040", "Return type of public static property getter from exported class has or is using private name '{0}'."),
+        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_modul_4041", "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named."),
+        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_4042", "Return type of public property getter from exported class has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0_4043", "Return type of public property getter from exported class has or is using private name '{0}'."),
+        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."),
+        Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."),
+        Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."),
+        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
+        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."),
+        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
+        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."),
+        Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."),
+        Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."),
+        Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."),
+        Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."),
+        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."),
+        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."),
+        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
+        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
+        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
+        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
+        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
+        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."),
+        Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."),
+        Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."),
+        Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."),
+        Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."),
+        Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."),
+        Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."),
+        Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Message, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."),
+        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."),
+        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."),
+        Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."),
+        The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."),
+        Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."),
+        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."),
+        File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0: diag(5011, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0_5011", "File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'."),
+        Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."),
+        Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."),
+        Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."),
+        Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."),
+        Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."),
+        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."),
+        Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."),
+        Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."),
+        Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."),
+        Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."),
+        A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."),
+        Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."),
+        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."),
+        Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."),
+        The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."),
+        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."),
+        Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."),
+        Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."),
+        Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' in can have at most one '*' character."),
+        Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."),
+        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."),
+        File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."),
+        Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."),
+        Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."),
+        Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."),
+        Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."),
+        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."),
+        Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."),
+        Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."),
+        Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."),
+        Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."),
+        Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."),
+        Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."),
+        Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."),
+        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."),
+        Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."),
+        Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."),
+        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."),
+        Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."),
+        Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."),
+        Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."),
+        Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."),
+        Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"),
+        options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"),
+        file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"),
+        Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"),
+        Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"),
+        Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"),
+        Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."),
+        File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."),
+        KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"),
+        FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"),
+        VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"),
+        LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"),
+        DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"),
+        STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"),
+        FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"),
+        Compilation_complete_Watching_for_file_changes: diag(6042, ts.DiagnosticCategory.Message, "Compilation_complete_Watching_for_file_changes_6042", "Compilation complete. Watching for file changes."),
+        Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."),
+        Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."),
+        Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."),
+        Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."),
+        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'."),
+        Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."),
+        Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."),
+        Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."),
+        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."),
+        File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."),
+        File_0_has_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has unsupported extension. The only supported extensions are {1}."),
+        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."),
+        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."),
+        Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."),
+        File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."),
+        Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."),
+        NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"),
+        Option_0_can_only_be_specified_in_tsconfig_json_file: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_6064", "Option '{0}' can only be specified in 'tsconfig.json' file."),
+        Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."),
+        Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."),
+        Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."),
+        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."),
+        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."),
+        Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."),
+        Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."),
+        Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."),
+        Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."),
+        Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."),
+        Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."),
+        Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."),
+        Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."),
+        Specify_library_files_to_be_included_in_the_compilation_Colon: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_Colon_6079", "Specify library files to be included in the compilation: "),
+        Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."),
+        File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."),
+        Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."),
+        Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."),
+        Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"),
+        Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."),
+        Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"),
+        Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."),
+        Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."),
+        Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"),
+        Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"),
+        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."),
+        Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."),
+        Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."),
+        Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."),
+        Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."),
+        File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."),
+        File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."),
+        Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."),
+        Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."),
+        package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."),
+        package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."),
+        Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."),
+        Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."),
+        Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."),
+        Expected_type_of_0_field_in_package_json_to_be_string_got_1: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105", "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'."),
+        baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."),
+        rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."),
+        Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."),
+        Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."),
+        Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."),
+        Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."),
+        Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."),
+        Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."),
+        Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"),
+        Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."),
+        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"),
+        Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."),
+        Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."),
+        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"),
+        Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"),
+        Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."),
+        Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."),
+        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"),
+        Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."),
+        Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."),
+        Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."),
+        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"),
+        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"),
+        Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."),
+        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."),
+        File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."),
+        _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read."),
+        Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."),
+        Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."),
+        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."),
+        Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."),
+        Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read."),
+        Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."),
+        Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."),
+        Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."),
+        Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."),
+        Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."),
+        Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."),
+        Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."),
+        Resolution_for_module_0_was_found_in_cache: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_6147", "Resolution for module '{0}' was found in cache."),
+        Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."),
+        Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."),
+        Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."),
+        Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."),
+        Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."),
+        Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."),
+        Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."),
+        Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."),
+        The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"),
+        Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."),
+        Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."),
+        Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."),
+        Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."),
+        List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."),
+        Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."),
+        The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."),
+        Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."),
+        Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."),
+        Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."),
+        A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."),
+        List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."),
+        Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."),
+        Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"),
+        Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"),
+        Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"),
+        Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"),
+        Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"),
+        Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"),
+        Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"),
+        Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"),
+        Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"),
+        Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."),
+        Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."),
+        List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."),
+        Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"),
+        Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."),
+        Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."),
+        Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."),
+        Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."),
+        Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."),
+        Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."),
+        Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."),
+        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."),
+        _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."),
+        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."),
+        Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."),
+        Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."),
+        Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."),
+        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."),
+        Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."),
+        Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."),
+        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."),
+        _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."),
+        _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
+        Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
+        Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025", "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type."),
+        JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."),
+        Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected."),
+        Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label."),
+        Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."),
+        Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."),
+        Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."),
+        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."),
+        Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."),
+        Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."),
+        Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"),
+        Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."),
+        You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."),
+        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."),
+        import_can_only_be_used_in_a_ts_file: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_a_ts_file_8002", "'import ... =' can only be used in a .ts file."),
+        export_can_only_be_used_in_a_ts_file: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_a_ts_file_8003", "'export=' can only be used in a .ts file."),
+        type_parameter_declarations_can_only_be_used_in_a_ts_file: diag(8004, ts.DiagnosticCategory.Error, "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004", "'type parameter declarations' can only be used in a .ts file."),
+        implements_clauses_can_only_be_used_in_a_ts_file: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_a_ts_file_8005", "'implements clauses' can only be used in a .ts file."),
+        interface_declarations_can_only_be_used_in_a_ts_file: diag(8006, ts.DiagnosticCategory.Error, "interface_declarations_can_only_be_used_in_a_ts_file_8006", "'interface declarations' can only be used in a .ts file."),
+        module_declarations_can_only_be_used_in_a_ts_file: diag(8007, ts.DiagnosticCategory.Error, "module_declarations_can_only_be_used_in_a_ts_file_8007", "'module declarations' can only be used in a .ts file."),
+        type_aliases_can_only_be_used_in_a_ts_file: diag(8008, ts.DiagnosticCategory.Error, "type_aliases_can_only_be_used_in_a_ts_file_8008", "'type aliases' can only be used in a .ts file."),
+        _0_can_only_be_used_in_a_ts_file: diag(8009, ts.DiagnosticCategory.Error, "_0_can_only_be_used_in_a_ts_file_8009", "'{0}' can only be used in a .ts file."),
+        types_can_only_be_used_in_a_ts_file: diag(8010, ts.DiagnosticCategory.Error, "types_can_only_be_used_in_a_ts_file_8010", "'types' can only be used in a .ts file."),
+        type_arguments_can_only_be_used_in_a_ts_file: diag(8011, ts.DiagnosticCategory.Error, "type_arguments_can_only_be_used_in_a_ts_file_8011", "'type arguments' can only be used in a .ts file."),
+        parameter_modifiers_can_only_be_used_in_a_ts_file: diag(8012, ts.DiagnosticCategory.Error, "parameter_modifiers_can_only_be_used_in_a_ts_file_8012", "'parameter modifiers' can only be used in a .ts file."),
+        non_null_assertions_can_only_be_used_in_a_ts_file: diag(8013, ts.DiagnosticCategory.Error, "non_null_assertions_can_only_be_used_in_a_ts_file_8013", "'non-null assertions' can only be used in a .ts file."),
+        enum_declarations_can_only_be_used_in_a_ts_file: diag(8015, ts.DiagnosticCategory.Error, "enum_declarations_can_only_be_used_in_a_ts_file_8015", "'enum declarations' can only be used in a .ts file."),
+        type_assertion_expressions_can_only_be_used_in_a_ts_file: diag(8016, ts.DiagnosticCategory.Error, "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016", "'type assertion expressions' can only be used in a .ts file."),
+        Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."),
+        Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."),
+        Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."),
+        JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."),
+        JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."),
+        JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."),
+        JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."),
+        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."),
+        Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."),
+        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."),
+        class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."),
+        Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."),
+        JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."),
+        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."),
+        Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."),
+        JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."),
+        Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."),
+        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."),
+        An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
+        A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
+        JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."),
+        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."),
+        Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."),
+        super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."),
+        _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"),
+        Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."),
+        Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"),
+        A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."),
+        The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."),
+        No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."),
+        Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call."),
+        Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor."),
+        Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'."),
+        Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'."),
+        Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'."),
+        Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class."),
+        Add_this_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_this_to_unresolved_variable_90008", "Add 'this.' to unresolved variable."),
+        Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(90009, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__90009", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."),
+        Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(90010, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_90010", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."),
+        Import_0_from_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_1_90013", "Import '{0}' from \"{1}\"."),
+        Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'."),
+        Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\"."),
+        Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'."),
+        Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'."),
+        Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file."),
+        Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message."),
+        Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor."),
+        Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'."),
+        Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'."),
+        Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'."),
+        Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'."),
+        Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore."),
+        Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."),
+        Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'."),
+        Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression."),
+        Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"),
+        Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"),
+        Extract_symbol: diag(95003, ts.DiagnosticCategory.Message, "Extract_symbol_95003", "Extract symbol"),
+        Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"),
+        Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"),
+        Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"),
+        Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"),
+        Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"),
+        Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"),
+        Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"),
+        Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage."),
+        Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage."),
+    };
+})(ts || (ts = {}));
+/// <reference path="core.ts"/>
+/// <reference path="diagnosticInformationMap.generated.ts"/>
+var ts;
+(function (ts) {
+    /* @internal */
+    function tokenIsIdentifierOrKeyword(token) {
+        return token >= 71 /* Identifier */;
+    }
+    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
+    var textToToken = ts.createMapFromTemplate({
+        "abstract": 117 /* AbstractKeyword */,
+        "any": 119 /* AnyKeyword */,
+        "as": 118 /* AsKeyword */,
+        "boolean": 122 /* BooleanKeyword */,
+        "break": 72 /* BreakKeyword */,
+        "case": 73 /* CaseKeyword */,
+        "catch": 74 /* CatchKeyword */,
+        "class": 75 /* ClassKeyword */,
+        "continue": 77 /* ContinueKeyword */,
+        "const": 76 /* ConstKeyword */,
+        "constructor": 123 /* ConstructorKeyword */,
+        "debugger": 78 /* DebuggerKeyword */,
+        "declare": 124 /* DeclareKeyword */,
+        "default": 79 /* DefaultKeyword */,
+        "delete": 80 /* DeleteKeyword */,
+        "do": 81 /* DoKeyword */,
+        "else": 82 /* ElseKeyword */,
+        "enum": 83 /* EnumKeyword */,
+        "export": 84 /* ExportKeyword */,
+        "extends": 85 /* ExtendsKeyword */,
+        "false": 86 /* FalseKeyword */,
+        "finally": 87 /* FinallyKeyword */,
+        "for": 88 /* ForKeyword */,
+        "from": 140 /* FromKeyword */,
+        "function": 89 /* FunctionKeyword */,
+        "get": 125 /* GetKeyword */,
+        "if": 90 /* IfKeyword */,
+        "implements": 108 /* ImplementsKeyword */,
+        "import": 91 /* ImportKeyword */,
+        "in": 92 /* InKeyword */,
+        "instanceof": 93 /* InstanceOfKeyword */,
+        "interface": 109 /* InterfaceKeyword */,
+        "is": 126 /* IsKeyword */,
+        "keyof": 127 /* KeyOfKeyword */,
+        "let": 110 /* LetKeyword */,
+        "module": 128 /* ModuleKeyword */,
+        "namespace": 129 /* NamespaceKeyword */,
+        "never": 130 /* NeverKeyword */,
+        "new": 94 /* NewKeyword */,
+        "null": 95 /* NullKeyword */,
+        "number": 133 /* NumberKeyword */,
+        "object": 134 /* ObjectKeyword */,
+        "package": 111 /* PackageKeyword */,
+        "private": 112 /* PrivateKeyword */,
+        "protected": 113 /* ProtectedKeyword */,
+        "public": 114 /* PublicKeyword */,
+        "readonly": 131 /* ReadonlyKeyword */,
+        "require": 132 /* RequireKeyword */,
+        "global": 141 /* GlobalKeyword */,
+        "return": 96 /* ReturnKeyword */,
+        "set": 135 /* SetKeyword */,
+        "static": 115 /* StaticKeyword */,
+        "string": 136 /* StringKeyword */,
+        "super": 97 /* SuperKeyword */,
+        "switch": 98 /* SwitchKeyword */,
+        "symbol": 137 /* SymbolKeyword */,
+        "this": 99 /* ThisKeyword */,
+        "throw": 100 /* ThrowKeyword */,
+        "true": 101 /* TrueKeyword */,
+        "try": 102 /* TryKeyword */,
+        "type": 138 /* TypeKeyword */,
+        "typeof": 103 /* TypeOfKeyword */,
+        "undefined": 139 /* UndefinedKeyword */,
+        "var": 104 /* VarKeyword */,
+        "void": 105 /* VoidKeyword */,
+        "while": 106 /* WhileKeyword */,
+        "with": 107 /* WithKeyword */,
+        "yield": 116 /* YieldKeyword */,
+        "async": 120 /* AsyncKeyword */,
+        "await": 121 /* AwaitKeyword */,
+        "of": 142 /* OfKeyword */,
+        "{": 17 /* OpenBraceToken */,
+        "}": 18 /* CloseBraceToken */,
+        "(": 19 /* OpenParenToken */,
+        ")": 20 /* CloseParenToken */,
+        "[": 21 /* OpenBracketToken */,
+        "]": 22 /* CloseBracketToken */,
+        ".": 23 /* DotToken */,
+        "...": 24 /* DotDotDotToken */,
+        ";": 25 /* SemicolonToken */,
+        ",": 26 /* CommaToken */,
+        "<": 27 /* LessThanToken */,
+        ">": 29 /* GreaterThanToken */,
+        "<=": 30 /* LessThanEqualsToken */,
+        ">=": 31 /* GreaterThanEqualsToken */,
+        "==": 32 /* EqualsEqualsToken */,
+        "!=": 33 /* ExclamationEqualsToken */,
+        "===": 34 /* EqualsEqualsEqualsToken */,
+        "!==": 35 /* ExclamationEqualsEqualsToken */,
+        "=>": 36 /* EqualsGreaterThanToken */,
+        "+": 37 /* PlusToken */,
+        "-": 38 /* MinusToken */,
+        "**": 40 /* AsteriskAsteriskToken */,
+        "*": 39 /* AsteriskToken */,
+        "/": 41 /* SlashToken */,
+        "%": 42 /* PercentToken */,
+        "++": 43 /* PlusPlusToken */,
+        "--": 44 /* MinusMinusToken */,
+        "<<": 45 /* LessThanLessThanToken */,
+        "</": 28 /* LessThanSlashToken */,
+        ">>": 46 /* GreaterThanGreaterThanToken */,
+        ">>>": 47 /* GreaterThanGreaterThanGreaterThanToken */,
+        "&": 48 /* AmpersandToken */,
+        "|": 49 /* BarToken */,
+        "^": 50 /* CaretToken */,
+        "!": 51 /* ExclamationToken */,
+        "~": 52 /* TildeToken */,
+        "&&": 53 /* AmpersandAmpersandToken */,
+        "||": 54 /* BarBarToken */,
+        "?": 55 /* QuestionToken */,
+        ":": 56 /* ColonToken */,
+        "=": 58 /* EqualsToken */,
+        "+=": 59 /* PlusEqualsToken */,
+        "-=": 60 /* MinusEqualsToken */,
+        "*=": 61 /* AsteriskEqualsToken */,
+        "**=": 62 /* AsteriskAsteriskEqualsToken */,
+        "/=": 63 /* SlashEqualsToken */,
+        "%=": 64 /* PercentEqualsToken */,
+        "<<=": 65 /* LessThanLessThanEqualsToken */,
+        ">>=": 66 /* GreaterThanGreaterThanEqualsToken */,
+        ">>>=": 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */,
+        "&=": 68 /* AmpersandEqualsToken */,
+        "|=": 69 /* BarEqualsToken */,
+        "^=": 70 /* CaretEqualsToken */,
+        "@": 57 /* AtToken */,
+    });
+    /*
+        As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
+        IdentifierStart ::
+            Can contain Unicode 3.0.0  categories:
+            Uppercase letter (Lu),
+            Lowercase letter (Ll),
+            Titlecase letter (Lt),
+            Modifier letter (Lm),
+            Other letter (Lo), or
+            Letter number (Nl).
+        IdentifierPart :: =
+            Can contain IdentifierStart + Unicode 3.0.0  categories:
+            Non-spacing mark (Mn),
+            Combining spacing mark (Mc),
+            Decimal number (Nd), or
+            Connector punctuation (Pc).
+
+        Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
+        http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
+    */
+    var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
+    var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
+    /*
+        As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
+        IdentifierStart ::
+            Can contain Unicode 6.2  categories:
+            Uppercase letter (Lu),
+            Lowercase letter (Ll),
+            Titlecase letter (Lt),
+            Modifier letter (Lm),
+            Other letter (Lo), or
+            Letter number (Nl).
+        IdentifierPart ::
+            Can contain IdentifierStart + Unicode 6.2  categories:
+            Non-spacing mark (Mn),
+            Combining spacing mark (Mc),
+            Decimal number (Nd),
+            Connector punctuation (Pc),
+            <ZWNJ>, or
+            <ZWJ>.
+
+        Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at:
+        http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
+    */
+    var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
+    var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
+    function lookupInUnicodeMap(code, map) {
+        // Bail out quickly if it couldn't possibly be in the map.
+        if (code < map[0]) {
+            return false;
+        }
+        // Perform binary search in one of the Unicode range maps
+        var lo = 0;
+        var hi = map.length;
+        var mid;
+        while (lo + 1 < hi) {
+            mid = lo + (hi - lo) / 2;
+            // mid has to be even to catch a range's beginning
+            mid -= mid % 2;
+            if (map[mid] <= code && code <= map[mid + 1]) {
+                return true;
+            }
+            if (code < map[mid]) {
+                hi = mid;
+            }
+            else {
+                lo = mid + 2;
+            }
+        }
+        return false;
+    }
+    /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) {
+        return languageVersion >= 1 /* ES5 */ ?
+            lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
+            lookupInUnicodeMap(code, unicodeES3IdentifierStart);
+    }
+    ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart;
+    function isUnicodeIdentifierPart(code, languageVersion) {
+        return languageVersion >= 1 /* ES5 */ ?
+            lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
+            lookupInUnicodeMap(code, unicodeES3IdentifierPart);
+    }
+    function makeReverseMap(source) {
+        var result = [];
+        source.forEach(function (value, name) {
+            result[value] = name;
+        });
+        return result;
+    }
+    var tokenStrings = makeReverseMap(textToToken);
+    function tokenToString(t) {
+        return tokenStrings[t];
+    }
+    ts.tokenToString = tokenToString;
+    /* @internal */
+    function stringToToken(s) {
+        return textToToken.get(s);
+    }
+    ts.stringToToken = stringToToken;
+    /* @internal */
+    function computeLineStarts(text) {
+        var result = new Array();
+        var pos = 0;
+        var lineStart = 0;
+        while (pos < text.length) {
+            var ch = text.charCodeAt(pos);
+            pos++;
+            switch (ch) {
+                case 13 /* carriageReturn */:
+                    if (text.charCodeAt(pos) === 10 /* lineFeed */) {
+                        pos++;
+                    }
+                // falls through
+                case 10 /* lineFeed */:
+                    result.push(lineStart);
+                    lineStart = pos;
+                    break;
+                default:
+                    if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
+                        result.push(lineStart);
+                        lineStart = pos;
+                    }
+                    break;
+            }
+        }
+        result.push(lineStart);
+        return result;
+    }
+    ts.computeLineStarts = computeLineStarts;
+    function getPositionOfLineAndCharacter(sourceFile, line, character) {
+        return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text);
+    }
+    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
+    /* @internal */
+    function computePositionOfLineAndCharacter(lineStarts, line, character, debugText) {
+        ts.Debug.assert(line >= 0 && line < lineStarts.length);
+        var res = lineStarts[line] + character;
+        if (line < lineStarts.length - 1) {
+            ts.Debug.assert(res < lineStarts[line + 1]);
+        }
+        else if (debugText !== undefined) {
+            ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
+        }
+        return res;
+    }
+    ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter;
+    /* @internal */
+    function getLineStarts(sourceFile) {
+        return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
+    }
+    ts.getLineStarts = getLineStarts;
+    /* @internal */
+    /**
+     * We assume the first line starts at position 0 and 'position' is non-negative.
+     */
+    function computeLineAndCharacterOfPosition(lineStarts, position) {
+        var lineNumber = ts.binarySearch(lineStarts, position);
+        if (lineNumber < 0) {
+            // If the actual position was not found,
+            // the binary search returns the 2's-complement of the next line start
+            // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
+            // then the search will return -2.
+            //
+            // We want the index of the previous line start, so we subtract 1.
+            // Review 2's-complement if this is confusing.
+            lineNumber = ~lineNumber - 1;
+            ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
+        }
+        return {
+            line: lineNumber,
+            character: position - lineStarts[lineNumber]
+        };
+    }
+    ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition;
+    function getLineAndCharacterOfPosition(sourceFile, position) {
+        return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
+    }
+    ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
+    function isWhiteSpaceLike(ch) {
+        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
+    }
+    ts.isWhiteSpaceLike = isWhiteSpaceLike;
+    /** Does not include line breaks. For that, see isWhiteSpaceLike. */
+    function isWhiteSpaceSingleLine(ch) {
+        // Note: nextLine is in the Zs space, and should be considered to be a whitespace.
+        // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
+        return ch === 32 /* space */ ||
+            ch === 9 /* tab */ ||
+            ch === 11 /* verticalTab */ ||
+            ch === 12 /* formFeed */ ||
+            ch === 160 /* nonBreakingSpace */ ||
+            ch === 133 /* nextLine */ ||
+            ch === 5760 /* ogham */ ||
+            ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
+            ch === 8239 /* narrowNoBreakSpace */ ||
+            ch === 8287 /* mathematicalSpace */ ||
+            ch === 12288 /* ideographicSpace */ ||
+            ch === 65279 /* byteOrderMark */;
+    }
+    ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine;
+    function isLineBreak(ch) {
+        // ES5 7.3:
+        // The ECMAScript line terminator characters are listed in Table 3.
+        //     Table 3: Line Terminator Characters
+        //     Code Unit Value     Name                    Formal Name
+        //     \u000A              Line Feed               <LF>
+        //     \u000D              Carriage Return         <CR>
+        //     \u2028              Line separator          <LS>
+        //     \u2029              Paragraph separator     <PS>
+        // Only the characters in Table 3 are treated as line terminators. Other new line or line
+        // breaking characters are treated as white space but not as line terminators.
+        return ch === 10 /* lineFeed */ ||
+            ch === 13 /* carriageReturn */ ||
+            ch === 8232 /* lineSeparator */ ||
+            ch === 8233 /* paragraphSeparator */;
+    }
+    ts.isLineBreak = isLineBreak;
+    function isDigit(ch) {
+        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
+    }
+    /* @internal */
+    function isOctalDigit(ch) {
+        return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
+    }
+    ts.isOctalDigit = isOctalDigit;
+    function couldStartTrivia(text, pos) {
+        // Keep in sync with skipTrivia
+        var ch = text.charCodeAt(pos);
+        switch (ch) {
+            case 13 /* carriageReturn */:
+            case 10 /* lineFeed */:
+            case 9 /* tab */:
+            case 11 /* verticalTab */:
+            case 12 /* formFeed */:
+            case 32 /* space */:
+            case 47 /* slash */:
+            // starts of normal trivia
+            case 60 /* lessThan */:
+            case 124 /* bar */:
+            case 61 /* equals */:
+            case 62 /* greaterThan */:
+                // Starts of conflict marker trivia
+                return true;
+            case 35 /* hash */:
+                // Only if its the beginning can we have #! trivia
+                return pos === 0;
+            default:
+                return ch > 127 /* maxAsciiCharacter */;
+        }
+    }
+    ts.couldStartTrivia = couldStartTrivia;
+    /* @internal */
+    function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) {
+        if (stopAtComments === void 0) { stopAtComments = false; }
+        if (ts.positionIsSynthesized(pos)) {
+            return pos;
+        }
+        // Keep in sync with couldStartTrivia
+        while (true) {
+            var ch = text.charCodeAt(pos);
+            switch (ch) {
+                case 13 /* carriageReturn */:
+                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
+                        pos++;
+                    }
+                // falls through
+                case 10 /* lineFeed */:
+                    pos++;
+                    if (stopAfterLineBreak) {
+                        return pos;
+                    }
+                    continue;
+                case 9 /* tab */:
+                case 11 /* verticalTab */:
+                case 12 /* formFeed */:
+                case 32 /* space */:
+                    pos++;
+                    continue;
+                case 47 /* slash */:
+                    if (stopAtComments) {
+                        break;
+                    }
+                    if (text.charCodeAt(pos + 1) === 47 /* slash */) {
+                        pos += 2;
+                        while (pos < text.length) {
+                            if (isLineBreak(text.charCodeAt(pos))) {
+                                break;
+                            }
+                            pos++;
+                        }
+                        continue;
+                    }
+                    if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
+                        pos += 2;
+                        while (pos < text.length) {
+                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
+                                pos += 2;
+                                break;
+                            }
+                            pos++;
+                        }
+                        continue;
+                    }
+                    break;
+                case 60 /* lessThan */:
+                case 124 /* bar */:
+                case 61 /* equals */:
+                case 62 /* greaterThan */:
+                    if (isConflictMarkerTrivia(text, pos)) {
+                        pos = scanConflictMarkerTrivia(text, pos);
+                        continue;
+                    }
+                    break;
+                case 35 /* hash */:
+                    if (pos === 0 && isShebangTrivia(text, pos)) {
+                        pos = scanShebangTrivia(text, pos);
+                        continue;
+                    }
+                    break;
+                default:
+                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
+                        pos++;
+                        continue;
+                    }
+                    break;
+            }
+            return pos;
+        }
+    }
+    ts.skipTrivia = skipTrivia;
+    // All conflict markers consist of the same character repeated seven times.  If it is
+    // a <<<<<<< or >>>>>>> marker then it is also followed by a space.
+    var mergeConflictMarkerLength = "<<<<<<<".length;
+    function isConflictMarkerTrivia(text, pos) {
+        ts.Debug.assert(pos >= 0);
+        // Conflict markers must be at the start of a line.
+        if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) {
+            var ch = text.charCodeAt(pos);
+            if ((pos + mergeConflictMarkerLength) < text.length) {
+                for (var i = 0; i < mergeConflictMarkerLength; i++) {
+                    if (text.charCodeAt(pos + i) !== ch) {
+                        return false;
+                    }
+                }
+                return ch === 61 /* equals */ ||
+                    text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */;
+            }
+        }
+        return false;
+    }
+    function scanConflictMarkerTrivia(text, pos, error) {
+        if (error) {
+            error(ts.Diagnostics.Merge_conflict_marker_encountered, mergeConflictMarkerLength);
+        }
+        var ch = text.charCodeAt(pos);
+        var len = text.length;
+        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
+            while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
+                pos++;
+            }
+        }
+        else {
+            ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
+            // Consume everything from the start of a ||||||| or ======= marker to the start
+            // of the next ======= or >>>>>>> marker.
+            while (pos < len) {
+                var currentChar = text.charCodeAt(pos);
+                if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
+                    break;
+                }
+                pos++;
+            }
+        }
+        return pos;
+    }
+    var shebangTriviaRegex = /^#!.*/;
+    function isShebangTrivia(text, pos) {
+        // Shebangs check must only be done at the start of the file
+        ts.Debug.assert(pos === 0);
+        return shebangTriviaRegex.test(text);
+    }
+    function scanShebangTrivia(text, pos) {
+        var shebang = shebangTriviaRegex.exec(text)[0];
+        pos = pos + shebang.length;
+        return pos;
+    }
+    /**
+     * Invokes a callback for each comment range following the provided position.
+     *
+     * Single-line comment ranges include the leading double-slash characters but not the ending
+     * line break. Multi-line comment ranges include the leading slash-asterisk and trailing
+     * asterisk-slash characters.
+     *
+     * @param reduce If true, accumulates the result of calling the callback in a fashion similar
+     *      to reduceLeft. If false, iteration stops when the callback returns a truthy value.
+     * @param text The source text to scan.
+     * @param pos The position at which to start scanning.
+     * @param trailing If false, whitespace is skipped until the first line break and comments
+     *      between that location and the next token are returned. If true, comments occurring
+     *      between the given position and the next line break are returned.
+     * @param cb The callback to execute as each comment range is encountered.
+     * @param state A state value to pass to each iteration of the callback.
+     * @param initial An initial value to pass when accumulating results (when "reduce" is true).
+     * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
+     *      return value of the callback.
+     */
+    function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) {
+        var pendingPos;
+        var pendingEnd;
+        var pendingKind;
+        var pendingHasTrailingNewLine;
+        var hasPendingCommentRange = false;
+        var collecting = trailing || pos === 0;
+        var accumulator = initial;
+        scan: while (pos >= 0 && pos < text.length) {
+            var ch = text.charCodeAt(pos);
+            switch (ch) {
+                case 13 /* carriageReturn */:
+                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
+                        pos++;
+                    }
+                // falls through
+                case 10 /* lineFeed */:
+                    pos++;
+                    if (trailing) {
+                        break scan;
+                    }
+                    collecting = true;
+                    if (hasPendingCommentRange) {
+                        pendingHasTrailingNewLine = true;
+                    }
+                    continue;
+                case 9 /* tab */:
+                case 11 /* verticalTab */:
+                case 12 /* formFeed */:
+                case 32 /* space */:
+                    pos++;
+                    continue;
+                case 47 /* slash */:
+                    var nextChar = text.charCodeAt(pos + 1);
+                    var hasTrailingNewLine = false;
+                    if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
+                        var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */;
+                        var startPos = pos;
+                        pos += 2;
+                        if (nextChar === 47 /* slash */) {
+                            while (pos < text.length) {
+                                if (isLineBreak(text.charCodeAt(pos))) {
+                                    hasTrailingNewLine = true;
+                                    break;
+                                }
+                                pos++;
+                            }
+                        }
+                        else {
+                            while (pos < text.length) {
+                                if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
+                                    pos += 2;
+                                    break;
+                                }
+                                pos++;
+                            }
+                        }
+                        if (collecting) {
+                            if (hasPendingCommentRange) {
+                                accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
+                                if (!reduce && accumulator) {
+                                    // If we are not reducing and we have a truthy result, return it.
+                                    return accumulator;
+                                }
+                                hasPendingCommentRange = false;
+                            }
+                            pendingPos = startPos;
+                            pendingEnd = pos;
+                            pendingKind = kind;
+                            pendingHasTrailingNewLine = hasTrailingNewLine;
+                            hasPendingCommentRange = true;
+                        }
+                        continue;
+                    }
+                    break scan;
+                default:
+                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
+                        if (hasPendingCommentRange && isLineBreak(ch)) {
+                            pendingHasTrailingNewLine = true;
+                        }
+                        pos++;
+                        continue;
+                    }
+                    break scan;
+            }
+        }
+        if (hasPendingCommentRange) {
+            accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
+        }
+        return accumulator;
+    }
+    function forEachLeadingCommentRange(text, pos, cb, state) {
+        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
+    }
+    ts.forEachLeadingCommentRange = forEachLeadingCommentRange;
+    function forEachTrailingCommentRange(text, pos, cb, state) {
+        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
+    }
+    ts.forEachTrailingCommentRange = forEachTrailingCommentRange;
+    function reduceEachLeadingCommentRange(text, pos, cb, state, initial) {
+        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
+    }
+    ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange;
+    function reduceEachTrailingCommentRange(text, pos, cb, state, initial) {
+        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
+    }
+    ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange;
+    function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) {
+        if (!comments) {
+            comments = [];
+        }
+        comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine });
+        return comments;
+    }
+    function getLeadingCommentRanges(text, pos) {
+        return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
+    }
+    ts.getLeadingCommentRanges = getLeadingCommentRanges;
+    function getTrailingCommentRanges(text, pos) {
+        return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
+    }
+    ts.getTrailingCommentRanges = getTrailingCommentRanges;
+    /** Optionally, get the shebang */
+    function getShebang(text) {
+        var match = shebangTriviaRegex.exec(text);
+        if (match) {
+            return match[0];
+        }
+    }
+    ts.getShebang = getShebang;
+    function isIdentifierStart(ch, languageVersion) {
+        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
+            ch === 36 /* $ */ || ch === 95 /* _ */ ||
+            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
+    }
+    ts.isIdentifierStart = isIdentifierStart;
+    function isIdentifierPart(ch, languageVersion) {
+        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
+            ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ ||
+            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
+    }
+    ts.isIdentifierPart = isIdentifierPart;
+    /* @internal */
+    function isIdentifierText(name, languageVersion) {
+        if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
+            return false;
+        }
+        for (var i = 1; i < name.length; i++) {
+            if (!isIdentifierPart(name.charCodeAt(i), languageVersion)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    ts.isIdentifierText = isIdentifierText;
+    // Creates a scanner over a (possibly unspecified) range of a piece of text.
+    function createScanner(languageVersion, skipTrivia, languageVariant, text, onError, start, length) {
+        if (languageVariant === void 0) { languageVariant = 0 /* Standard */; }
+        // Current position (end position of text of current token)
+        var pos;
+        // end of text
+        var end;
+        // Start position of whitespace before current token
+        var startPos;
+        // Start position of text of current token
+        var tokenPos;
+        var token;
+        var tokenValue;
+        var precedingLineBreak;
+        var hasExtendedUnicodeEscape;
+        var tokenIsUnterminated;
+        var numericLiteralFlags;
+        setText(text, start, length);
+        return {
+            getStartPos: function () { return startPos; },
+            getTextPos: function () { return pos; },
+            getToken: function () { return token; },
+            getTokenPos: function () { return tokenPos; },
+            getTokenText: function () { return text.substring(tokenPos, pos); },
+            getTokenValue: function () { return tokenValue; },
+            hasExtendedUnicodeEscape: function () { return hasExtendedUnicodeEscape; },
+            hasPrecedingLineBreak: function () { return precedingLineBreak; },
+            isIdentifier: function () { return token === 71 /* Identifier */ || token > 107 /* LastReservedWord */; },
+            isReservedWord: function () { return token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */; },
+            isUnterminated: function () { return tokenIsUnterminated; },
+            getNumericLiteralFlags: function () { return numericLiteralFlags; },
+            reScanGreaterToken: reScanGreaterToken,
+            reScanSlashToken: reScanSlashToken,
+            reScanTemplateToken: reScanTemplateToken,
+            scanJsxIdentifier: scanJsxIdentifier,
+            scanJsxAttributeValue: scanJsxAttributeValue,
+            reScanJsxToken: reScanJsxToken,
+            scanJsxToken: scanJsxToken,
+            scanJSDocToken: scanJSDocToken,
+            scan: scan,
+            getText: getText,
+            setText: setText,
+            setScriptTarget: setScriptTarget,
+            setLanguageVariant: setLanguageVariant,
+            setOnError: setOnError,
+            setTextPos: setTextPos,
+            tryScan: tryScan,
+            lookAhead: lookAhead,
+            scanRange: scanRange,
+        };
+        function error(message, length) {
+            if (onError) {
+                onError(message, length || 0);
+            }
+        }
+        function scanNumber() {
+            var start = pos;
+            while (isDigit(text.charCodeAt(pos)))
+                pos++;
+            if (text.charCodeAt(pos) === 46 /* dot */) {
+                pos++;
+                while (isDigit(text.charCodeAt(pos)))
+                    pos++;
+            }
+            var end = pos;
+            if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
+                pos++;
+                numericLiteralFlags = 2 /* Scientific */;
+                if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
+                    pos++;
+                if (isDigit(text.charCodeAt(pos))) {
+                    pos++;
+                    while (isDigit(text.charCodeAt(pos)))
+                        pos++;
+                    end = pos;
+                }
+                else {
+                    error(ts.Diagnostics.Digit_expected);
+                }
+            }
+            return "" + +(text.substring(start, end));
+        }
+        function scanOctalDigits() {
+            var start = pos;
+            while (isOctalDigit(text.charCodeAt(pos))) {
+                pos++;
+            }
+            return +(text.substring(start, pos));
+        }
+        /**
+         * Scans the given number of hexadecimal digits in the text,
+         * returning -1 if the given number is unavailable.
+         */
+        function scanExactNumberOfHexDigits(count) {
+            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false);
+        }
+        /**
+         * Scans as many hexadecimal digits as are available in the text,
+         * returning -1 if the given number of digits was unavailable.
+         */
+        function scanMinimumNumberOfHexDigits(count) {
+            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true);
+        }
+        function scanHexDigits(minCount, scanAsManyAsPossible) {
+            var digits = 0;
+            var value = 0;
+            while (digits < minCount || scanAsManyAsPossible) {
+                var ch = text.charCodeAt(pos);
+                if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
+                    value = value * 16 + ch - 48 /* _0 */;
+                }
+                else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
+                    value = value * 16 + ch - 65 /* A */ + 10;
+                }
+                else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
+                    value = value * 16 + ch - 97 /* a */ + 10;
+                }
+                else {
+                    break;
+                }
+                pos++;
+                digits++;
+            }
+            if (digits < minCount) {
+                value = -1;
+            }
+            return value;
+        }
+        function scanString(allowEscapes) {
+            if (allowEscapes === void 0) { allowEscapes = true; }
+            var quote = text.charCodeAt(pos);
+            pos++;
+            var result = "";
+            var start = pos;
+            while (true) {
+                if (pos >= end) {
+                    result += text.substring(start, pos);
+                    tokenIsUnterminated = true;
+                    error(ts.Diagnostics.Unterminated_string_literal);
+                    break;
+                }
+                var ch = text.charCodeAt(pos);
+                if (ch === quote) {
+                    result += text.substring(start, pos);
+                    pos++;
+                    break;
+                }
+                if (ch === 92 /* backslash */ && allowEscapes) {
+                    result += text.substring(start, pos);
+                    result += scanEscapeSequence();
+                    start = pos;
+                    continue;
+                }
+                if (isLineBreak(ch)) {
+                    result += text.substring(start, pos);
+                    tokenIsUnterminated = true;
+                    error(ts.Diagnostics.Unterminated_string_literal);
+                    break;
+                }
+                pos++;
+            }
+            return result;
+        }
+        /**
+         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
+         * a literal component of a TemplateExpression.
+         */
+        function scanTemplateAndSetTokenValue() {
+            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
+            pos++;
+            var start = pos;
+            var contents = "";
+            var resultingToken;
+            while (true) {
+                if (pos >= end) {
+                    contents += text.substring(start, pos);
+                    tokenIsUnterminated = true;
+                    error(ts.Diagnostics.Unterminated_template_literal);
+                    resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */;
+                    break;
+                }
+                var currChar = text.charCodeAt(pos);
+                // '`'
+                if (currChar === 96 /* backtick */) {
+                    contents += text.substring(start, pos);
+                    pos++;
+                    resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */;
+                    break;
+                }
+                // '${'
+                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
+                    contents += text.substring(start, pos);
+                    pos += 2;
+                    resultingToken = startedWithBacktick ? 14 /* TemplateHead */ : 15 /* TemplateMiddle */;
+                    break;
+                }
+                // Escape character
+                if (currChar === 92 /* backslash */) {
+                    contents += text.substring(start, pos);
+                    contents += scanEscapeSequence();
+                    start = pos;
+                    continue;
+                }
+                // Speculated ECMAScript 6 Spec 11.8.6.1:
+                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
+                if (currChar === 13 /* carriageReturn */) {
+                    contents += text.substring(start, pos);
+                    pos++;
+                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
+                        pos++;
+                    }
+                    contents += "\n";
+                    start = pos;
+                    continue;
+                }
+                pos++;
+            }
+            ts.Debug.assert(resultingToken !== undefined);
+            tokenValue = contents;
+            return resultingToken;
+        }
+        function scanEscapeSequence() {
+            pos++;
+            if (pos >= end) {
+                error(ts.Diagnostics.Unexpected_end_of_text);
+                return "";
+            }
+            var ch = text.charCodeAt(pos);
+            pos++;
+            switch (ch) {
+                case 48 /* _0 */:
+                    return "\0";
+                case 98 /* b */:
+                    return "\b";
+                case 116 /* t */:
+                    return "\t";
+                case 110 /* n */:
+                    return "\n";
+                case 118 /* v */:
+                    return "\v";
+                case 102 /* f */:
+                    return "\f";
+                case 114 /* r */:
+                    return "\r";
+                case 39 /* singleQuote */:
+                    return "\'";
+                case 34 /* doubleQuote */:
+                    return "\"";
+                case 117 /* u */:
+                    // '\u{DDDDDDDD}'
+                    if (pos < end && text.charCodeAt(pos) === 123 /* openBrace */) {
+                        hasExtendedUnicodeEscape = true;
+                        pos++;
+                        return scanExtendedUnicodeEscape();
+                    }
+                    // '\uDDDD'
+                    return scanHexadecimalEscape(/*numDigits*/ 4);
+                case 120 /* x */:
+                    // '\xDD'
+                    return scanHexadecimalEscape(/*numDigits*/ 2);
+                // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
+                // the line terminator is interpreted to be "the empty code unit sequence".
+                case 13 /* carriageReturn */:
+                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
+                        pos++;
+                    }
+                // falls through
+                case 10 /* lineFeed */:
+                case 8232 /* lineSeparator */:
+                case 8233 /* paragraphSeparator */:
+                    return "";
+                default:
+                    return String.fromCharCode(ch);
+            }
+        }
+        function scanHexadecimalEscape(numDigits) {
+            var escapedValue = scanExactNumberOfHexDigits(numDigits);
+            if (escapedValue >= 0) {
+                return String.fromCharCode(escapedValue);
+            }
+            else {
+                error(ts.Diagnostics.Hexadecimal_digit_expected);
+                return "";
+            }
+        }
+        function scanExtendedUnicodeEscape() {
+            var escapedValue = scanMinimumNumberOfHexDigits(1);
+            var isInvalidExtendedEscape = false;
+            // Validate the value of the digit
+            if (escapedValue < 0) {
+                error(ts.Diagnostics.Hexadecimal_digit_expected);
+                isInvalidExtendedEscape = true;
+            }
+            else if (escapedValue > 0x10FFFF) {
+                error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive);
+                isInvalidExtendedEscape = true;
+            }
+            if (pos >= end) {
+                error(ts.Diagnostics.Unexpected_end_of_text);
+                isInvalidExtendedEscape = true;
+            }
+            else if (text.charCodeAt(pos) === 125 /* closeBrace */) {
+                // Only swallow the following character up if it's a '}'.
+                pos++;
+            }
+            else {
+                error(ts.Diagnostics.Unterminated_Unicode_escape_sequence);
+                isInvalidExtendedEscape = true;
+            }
+            if (isInvalidExtendedEscape) {
+                return "";
+            }
+            return utf16EncodeAsString(escapedValue);
+        }
+        // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.
+        function utf16EncodeAsString(codePoint) {
+            ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
+            if (codePoint <= 65535) {
+                return String.fromCharCode(codePoint);
+            }
+            var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
+            var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
+            return String.fromCharCode(codeUnit1, codeUnit2);
+        }
+        // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
+        // and return code point value if valid Unicode escape is found. Otherwise return -1.
+        function peekUnicodeEscape() {
+            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
+                var start_1 = pos;
+                pos += 2;
+                var value = scanExactNumberOfHexDigits(4);
+                pos = start_1;
+                return value;
+            }
+            return -1;
+        }
+        function scanIdentifierParts() {
+            var result = "";
+            var start = pos;
+            while (pos < end) {
+                var ch = text.charCodeAt(pos);
+                if (isIdentifierPart(ch, languageVersion)) {
+                    pos++;
+                }
+                else if (ch === 92 /* backslash */) {
+                    ch = peekUnicodeEscape();
+                    if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
+                        break;
+                    }
+                    result += text.substring(start, pos);
+                    result += String.fromCharCode(ch);
+                    // Valid Unicode escape is always six characters
+                    pos += 6;
+                    start = pos;
+                }
+                else {
+                    break;
+                }
+            }
+            result += text.substring(start, pos);
+            return result;
+        }
+        function getIdentifierToken() {
+            // Reserved words are between 2 and 11 characters long and start with a lowercase letter
+            var len = tokenValue.length;
+            if (len >= 2 && len <= 11) {
+                var ch = tokenValue.charCodeAt(0);
+                if (ch >= 97 /* a */ && ch <= 122 /* z */) {
+                    token = textToToken.get(tokenValue);
+                    if (token !== undefined) {
+                        return token;
+                    }
+                }
+            }
+            return token = 71 /* Identifier */;
+        }
+        function scanBinaryOrOctalDigits(base) {
+            ts.Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
+            var value = 0;
+            // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
+            // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
+            var numberOfDigits = 0;
+            while (true) {
+                var ch = text.charCodeAt(pos);
+                var valueOfCh = ch - 48 /* _0 */;
+                if (!isDigit(ch) || valueOfCh >= base) {
+                    break;
+                }
+                value = value * base + valueOfCh;
+                pos++;
+                numberOfDigits++;
+            }
+            // Invalid binaryIntegerLiteral or octalIntegerLiteral
+            if (numberOfDigits === 0) {
+                return -1;
+            }
+            return value;
+        }
+        function scan() {
+            startPos = pos;
+            hasExtendedUnicodeEscape = false;
+            precedingLineBreak = false;
+            tokenIsUnterminated = false;
+            numericLiteralFlags = 0;
+            while (true) {
+                tokenPos = pos;
+                if (pos >= end) {
+                    return token = 1 /* EndOfFileToken */;
+                }
+                var ch = text.charCodeAt(pos);
+                // Special handling for shebang
+                if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) {
+                    pos = scanShebangTrivia(text, pos);
+                    if (skipTrivia) {
+                        continue;
+                    }
+                    else {
+                        return token = 6 /* ShebangTrivia */;
+                    }
+                }
+                switch (ch) {
+                    case 10 /* lineFeed */:
+                    case 13 /* carriageReturn */:
+                        precedingLineBreak = true;
+                        if (skipTrivia) {
+                            pos++;
+                            continue;
+                        }
+                        else {
+                            if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
+                                // consume both CR and LF
+                                pos += 2;
+                            }
+                            else {
+                                pos++;
+                            }
+                            return token = 4 /* NewLineTrivia */;
+                        }
+                    case 9 /* tab */:
+                    case 11 /* verticalTab */:
+                    case 12 /* formFeed */:
+                    case 32 /* space */:
+                        if (skipTrivia) {
+                            pos++;
+                            continue;
+                        }
+                        else {
+                            while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
+                                pos++;
+                            }
+                            return token = 5 /* WhitespaceTrivia */;
+                        }
+                    case 33 /* exclamation */:
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
+                                return pos += 3, token = 35 /* ExclamationEqualsEqualsToken */;
+                            }
+                            return pos += 2, token = 33 /* ExclamationEqualsToken */;
+                        }
+                        pos++;
+                        return token = 51 /* ExclamationToken */;
+                    case 34 /* doubleQuote */:
+                    case 39 /* singleQuote */:
+                        tokenValue = scanString();
+                        return token = 9 /* StringLiteral */;
+                    case 96 /* backtick */:
+                        return token = scanTemplateAndSetTokenValue();
+                    case 37 /* percent */:
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 64 /* PercentEqualsToken */;
+                        }
+                        pos++;
+                        return token = 42 /* PercentToken */;
+                    case 38 /* ampersand */:
+                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
+                            return pos += 2, token = 53 /* AmpersandAmpersandToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 68 /* AmpersandEqualsToken */;
+                        }
+                        pos++;
+                        return token = 48 /* AmpersandToken */;
+                    case 40 /* openParen */:
+                        pos++;
+                        return token = 19 /* OpenParenToken */;
+                    case 41 /* closeParen */:
+                        pos++;
+                        return token = 20 /* CloseParenToken */;
+                    case 42 /* asterisk */:
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 61 /* AsteriskEqualsToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
+                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
+                                return pos += 3, token = 62 /* AsteriskAsteriskEqualsToken */;
+                            }
+                            return pos += 2, token = 40 /* AsteriskAsteriskToken */;
+                        }
+                        pos++;
+                        return token = 39 /* AsteriskToken */;
+                    case 43 /* plus */:
+                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
+                            return pos += 2, token = 43 /* PlusPlusToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 59 /* PlusEqualsToken */;
+                        }
+                        pos++;
+                        return token = 37 /* PlusToken */;
+                    case 44 /* comma */:
+                        pos++;
+                        return token = 26 /* CommaToken */;
+                    case 45 /* minus */:
+                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
+                            return pos += 2, token = 44 /* MinusMinusToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 60 /* MinusEqualsToken */;
+                        }
+                        pos++;
+                        return token = 38 /* MinusToken */;
+                    case 46 /* dot */:
+                        if (isDigit(text.charCodeAt(pos + 1))) {
+                            tokenValue = scanNumber();
+                            return token = 8 /* NumericLiteral */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
+                            return pos += 3, token = 24 /* DotDotDotToken */;
+                        }
+                        pos++;
+                        return token = 23 /* DotToken */;
+                    case 47 /* slash */:
+                        // Single-line comment
+                        if (text.charCodeAt(pos + 1) === 47 /* slash */) {
+                            pos += 2;
+                            while (pos < end) {
+                                if (isLineBreak(text.charCodeAt(pos))) {
+                                    break;
+                                }
+                                pos++;
+                            }
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                return token = 2 /* SingleLineCommentTrivia */;
+                            }
+                        }
+                        // Multi-line comment
+                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
+                            pos += 2;
+                            var commentClosed = false;
+                            while (pos < end) {
+                                var ch_1 = text.charCodeAt(pos);
+                                if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
+                                    pos += 2;
+                                    commentClosed = true;
+                                    break;
+                                }
+                                if (isLineBreak(ch_1)) {
+                                    precedingLineBreak = true;
+                                }
+                                pos++;
+                            }
+                            if (!commentClosed) {
+                                error(ts.Diagnostics.Asterisk_Slash_expected);
+                            }
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                tokenIsUnterminated = !commentClosed;
+                                return token = 3 /* MultiLineCommentTrivia */;
+                            }
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 63 /* SlashEqualsToken */;
+                        }
+                        pos++;
+                        return token = 41 /* SlashToken */;
+                    case 48 /* _0 */:
+                        if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
+                            pos += 2;
+                            var value = scanMinimumNumberOfHexDigits(1);
+                            if (value < 0) {
+                                error(ts.Diagnostics.Hexadecimal_digit_expected);
+                                value = 0;
+                            }
+                            tokenValue = "" + value;
+                            numericLiteralFlags = 8 /* HexSpecifier */;
+                            return token = 8 /* NumericLiteral */;
+                        }
+                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) {
+                            pos += 2;
+                            var value = scanBinaryOrOctalDigits(/* base */ 2);
+                            if (value < 0) {
+                                error(ts.Diagnostics.Binary_digit_expected);
+                                value = 0;
+                            }
+                            tokenValue = "" + value;
+                            numericLiteralFlags = 16 /* BinarySpecifier */;
+                            return token = 8 /* NumericLiteral */;
+                        }
+                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) {
+                            pos += 2;
+                            var value = scanBinaryOrOctalDigits(/* base */ 8);
+                            if (value < 0) {
+                                error(ts.Diagnostics.Octal_digit_expected);
+                                value = 0;
+                            }
+                            tokenValue = "" + value;
+                            numericLiteralFlags = 32 /* OctalSpecifier */;
+                            return token = 8 /* NumericLiteral */;
+                        }
+                        // Try to parse as an octal
+                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
+                            tokenValue = "" + scanOctalDigits();
+                            numericLiteralFlags = 4 /* Octal */;
+                            return token = 8 /* NumericLiteral */;
+                        }
+                    // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
+                    // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
+                    // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
+                    // falls through
+                    case 49 /* _1 */:
+                    case 50 /* _2 */:
+                    case 51 /* _3 */:
+                    case 52 /* _4 */:
+                    case 53 /* _5 */:
+                    case 54 /* _6 */:
+                    case 55 /* _7 */:
+                    case 56 /* _8 */:
+                    case 57 /* _9 */:
+                        tokenValue = scanNumber();
+                        return token = 8 /* NumericLiteral */;
+                    case 58 /* colon */:
+                        pos++;
+                        return token = 56 /* ColonToken */;
+                    case 59 /* semicolon */:
+                        pos++;
+                        return token = 25 /* SemicolonToken */;
+                    case 60 /* lessThan */:
+                        if (isConflictMarkerTrivia(text, pos)) {
+                            pos = scanConflictMarkerTrivia(text, pos, error);
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                return token = 7 /* ConflictMarkerTrivia */;
+                            }
+                        }
+                        if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
+                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
+                                return pos += 3, token = 65 /* LessThanLessThanEqualsToken */;
+                            }
+                            return pos += 2, token = 45 /* LessThanLessThanToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 30 /* LessThanEqualsToken */;
+                        }
+                        if (languageVariant === 1 /* JSX */ &&
+                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
+                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
+                            return pos += 2, token = 28 /* LessThanSlashToken */;
+                        }
+                        pos++;
+                        return token = 27 /* LessThanToken */;
+                    case 61 /* equals */:
+                        if (isConflictMarkerTrivia(text, pos)) {
+                            pos = scanConflictMarkerTrivia(text, pos, error);
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                return token = 7 /* ConflictMarkerTrivia */;
+                            }
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
+                                return pos += 3, token = 34 /* EqualsEqualsEqualsToken */;
+                            }
+                            return pos += 2, token = 32 /* EqualsEqualsToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
+                            return pos += 2, token = 36 /* EqualsGreaterThanToken */;
+                        }
+                        pos++;
+                        return token = 58 /* EqualsToken */;
+                    case 62 /* greaterThan */:
+                        if (isConflictMarkerTrivia(text, pos)) {
+                            pos = scanConflictMarkerTrivia(text, pos, error);
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                return token = 7 /* ConflictMarkerTrivia */;
+                            }
+                        }
+                        pos++;
+                        return token = 29 /* GreaterThanToken */;
+                    case 63 /* question */:
+                        pos++;
+                        return token = 55 /* QuestionToken */;
+                    case 91 /* openBracket */:
+                        pos++;
+                        return token = 21 /* OpenBracketToken */;
+                    case 93 /* closeBracket */:
+                        pos++;
+                        return token = 22 /* CloseBracketToken */;
+                    case 94 /* caret */:
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 70 /* CaretEqualsToken */;
+                        }
+                        pos++;
+                        return token = 50 /* CaretToken */;
+                    case 123 /* openBrace */:
+                        pos++;
+                        return token = 17 /* OpenBraceToken */;
+                    case 124 /* bar */:
+                        if (isConflictMarkerTrivia(text, pos)) {
+                            pos = scanConflictMarkerTrivia(text, pos, error);
+                            if (skipTrivia) {
+                                continue;
+                            }
+                            else {
+                                return token = 7 /* ConflictMarkerTrivia */;
+                            }
+                        }
+                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
+                            return pos += 2, token = 54 /* BarBarToken */;
+                        }
+                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                            return pos += 2, token = 69 /* BarEqualsToken */;
+                        }
+                        pos++;
+                        return token = 49 /* BarToken */;
+                    case 125 /* closeBrace */:
+                        pos++;
+                        return token = 18 /* CloseBraceToken */;
+                    case 126 /* tilde */:
+                        pos++;
+                        return token = 52 /* TildeToken */;
+                    case 64 /* at */:
+                        pos++;
+                        return token = 57 /* AtToken */;
+                    case 92 /* backslash */:
+                        var cookedChar = peekUnicodeEscape();
+                        if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
+                            pos += 6;
+                            tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
+                            return token = getIdentifierToken();
+                        }
+                        error(ts.Diagnostics.Invalid_character);
+                        pos++;
+                        return token = 0 /* Unknown */;
+                    default:
+                        if (isIdentifierStart(ch, languageVersion)) {
+                            pos++;
+                            while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion))
+                                pos++;
+                            tokenValue = text.substring(tokenPos, pos);
+                            if (ch === 92 /* backslash */) {
+                                tokenValue += scanIdentifierParts();
+                            }
+                            return token = getIdentifierToken();
+                        }
+                        else if (isWhiteSpaceSingleLine(ch)) {
+                            pos++;
+                            continue;
+                        }
+                        else if (isLineBreak(ch)) {
+                            precedingLineBreak = true;
+                            pos++;
+                            continue;
+                        }
+                        error(ts.Diagnostics.Invalid_character);
+                        pos++;
+                        return token = 0 /* Unknown */;
+                }
+            }
+        }
+        function reScanGreaterToken() {
+            if (token === 29 /* GreaterThanToken */) {
+                if (text.charCodeAt(pos) === 62 /* greaterThan */) {
+                    if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
+                        if (text.charCodeAt(pos + 2) === 61 /* equals */) {
+                            return pos += 3, token = 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
+                        }
+                        return pos += 2, token = 47 /* GreaterThanGreaterThanGreaterThanToken */;
+                    }
+                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
+                        return pos += 2, token = 66 /* GreaterThanGreaterThanEqualsToken */;
+                    }
+                    pos++;
+                    return token = 46 /* GreaterThanGreaterThanToken */;
+                }
+                if (text.charCodeAt(pos) === 61 /* equals */) {
+                    pos++;
+                    return token = 31 /* GreaterThanEqualsToken */;
+                }
+            }
+            return token;
+        }
+        function reScanSlashToken() {
+            if (token === 41 /* SlashToken */ || token === 63 /* SlashEqualsToken */) {
+                var p = tokenPos + 1;
+                var inEscape = false;
+                var inCharacterClass = false;
+                while (true) {
+                    // If we reach the end of a file, or hit a newline, then this is an unterminated
+                    // regex.  Report error and return what we have so far.
+                    if (p >= end) {
+                        tokenIsUnterminated = true;
+                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
+                        break;
+                    }
+                    var ch = text.charCodeAt(p);
+                    if (isLineBreak(ch)) {
+                        tokenIsUnterminated = true;
+                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
+                        break;
+                    }
+                    if (inEscape) {
+                        // Parsing an escape character;
+                        // reset the flag and just advance to the next char.
+                        inEscape = false;
+                    }
+                    else if (ch === 47 /* slash */ && !inCharacterClass) {
+                        // A slash within a character class is permissible,
+                        // but in general it signals the end of the regexp literal.
+                        p++;
+                        break;
+                    }
+                    else if (ch === 91 /* openBracket */) {
+                        inCharacterClass = true;
+                    }
+                    else if (ch === 92 /* backslash */) {
+                        inEscape = true;
+                    }
+                    else if (ch === 93 /* closeBracket */) {
+                        inCharacterClass = false;
+                    }
+                    p++;
+                }
+                while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
+                    p++;
+                }
+                pos = p;
+                tokenValue = text.substring(tokenPos, pos);
+                token = 12 /* RegularExpressionLiteral */;
+            }
+            return token;
+        }
+        /**
+         * Unconditionally back up and scan a template expression portion.
+         */
+        function reScanTemplateToken() {
+            ts.Debug.assert(token === 18 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
+            pos = tokenPos;
+            return token = scanTemplateAndSetTokenValue();
+        }
+        function reScanJsxToken() {
+            pos = tokenPos = startPos;
+            return token = scanJsxToken();
+        }
+        function scanJsxToken() {
+            startPos = tokenPos = pos;
+            if (pos >= end) {
+                return token = 1 /* EndOfFileToken */;
+            }
+            var char = text.charCodeAt(pos);
+            if (char === 60 /* lessThan */) {
+                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
+                    pos += 2;
+                    return token = 28 /* LessThanSlashToken */;
+                }
+                pos++;
+                return token = 27 /* LessThanToken */;
+            }
+            if (char === 123 /* openBrace */) {
+                pos++;
+                return token = 17 /* OpenBraceToken */;
+            }
+            // First non-whitespace character on this line.
+            var firstNonWhitespace = 0;
+            // These initial values are special because the first line is:
+            // firstNonWhitespace = 0 to indicate that we want leading whitspace,
+            while (pos < end) {
+                char = text.charCodeAt(pos);
+                if (char === 123 /* openBrace */) {
+                    break;
+                }
+                if (char === 60 /* lessThan */) {
+                    if (isConflictMarkerTrivia(text, pos)) {
+                        pos = scanConflictMarkerTrivia(text, pos, error);
+                        return token = 7 /* ConflictMarkerTrivia */;
+                    }
+                    break;
+                }
+                // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
+                // i.e (- : whitespace)
+                //      <div>----
+                //      </div> becomes <div></div>
+                //
+                //      <div>----</div> becomes <div>----</div>
+                if (isLineBreak(char) && firstNonWhitespace === 0) {
+                    firstNonWhitespace = -1;
+                }
+                else if (!isWhiteSpaceLike(char)) {
+                    firstNonWhitespace = pos;
+                }
+                pos++;
+            }
+            return firstNonWhitespace === -1 ? 11 /* JsxTextAllWhiteSpaces */ : 10 /* JsxText */;
+        }
+        // Scans a JSX identifier; these differ from normal identifiers in that
+        // they allow dashes
+        function scanJsxIdentifier() {
+            if (tokenIsIdentifierOrKeyword(token)) {
+                var firstCharPosition = pos;
+                while (pos < end) {
+                    var ch = text.charCodeAt(pos);
+                    if (ch === 45 /* minus */ || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) {
+                        pos++;
+                    }
+                    else {
+                        break;
+                    }
+                }
+                tokenValue += text.substr(firstCharPosition, pos - firstCharPosition);
+            }
+            return token;
+        }
+        function scanJsxAttributeValue() {
+            startPos = pos;
+            switch (text.charCodeAt(pos)) {
+                case 34 /* doubleQuote */:
+                case 39 /* singleQuote */:
+                    tokenValue = scanString(/*allowEscapes*/ false);
+                    return token = 9 /* StringLiteral */;
+                default:
+                    // If this scans anything other than `{`, it's a parse error.
+                    return scan();
+            }
+        }
+        function scanJSDocToken() {
+            if (pos >= end) {
+                return token = 1 /* EndOfFileToken */;
+            }
+            startPos = pos;
+            tokenPos = pos;
+            var ch = text.charCodeAt(pos);
+            switch (ch) {
+                case 9 /* tab */:
+                case 11 /* verticalTab */:
+                case 12 /* formFeed */:
+                case 32 /* space */:
+                    while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
+                        pos++;
+                    }
+                    return token = 5 /* WhitespaceTrivia */;
+                case 64 /* at */:
+                    pos++;
+                    return token = 57 /* AtToken */;
+                case 10 /* lineFeed */:
+                case 13 /* carriageReturn */:
+                    pos++;
+                    return token = 4 /* NewLineTrivia */;
+                case 42 /* asterisk */:
+                    pos++;
+                    return token = 39 /* AsteriskToken */;
+                case 123 /* openBrace */:
+                    pos++;
+                    return token = 17 /* OpenBraceToken */;
+                case 125 /* closeBrace */:
+                    pos++;
+                    return token = 18 /* CloseBraceToken */;
+                case 91 /* openBracket */:
+                    pos++;
+                    return token = 21 /* OpenBracketToken */;
+                case 93 /* closeBracket */:
+                    pos++;
+                    return token = 22 /* CloseBracketToken */;
+                case 60 /* lessThan */:
+                    pos++;
+                    return token = 27 /* LessThanToken */;
+                case 62 /* greaterThan */:
+                    pos++;
+                    return token = 29 /* GreaterThanToken */;
+                case 61 /* equals */:
+                    pos++;
+                    return token = 58 /* EqualsToken */;
+                case 44 /* comma */:
+                    pos++;
+                    return token = 26 /* CommaToken */;
+                case 46 /* dot */:
+                    pos++;
+                    return token = 23 /* DotToken */;
+            }
+            if (isIdentifierStart(ch, 5 /* Latest */)) {
+                pos++;
+                while (isIdentifierPart(text.charCodeAt(pos), 5 /* Latest */) && pos < end) {
+                    pos++;
+                }
+                return token = 71 /* Identifier */;
+            }
+            else {
+                return pos += 1, token = 0 /* Unknown */;
+            }
+        }
+        function speculationHelper(callback, isLookahead) {
+            var savePos = pos;
+            var saveStartPos = startPos;
+            var saveTokenPos = tokenPos;
+            var saveToken = token;
+            var saveTokenValue = tokenValue;
+            var savePrecedingLineBreak = precedingLineBreak;
+            var result = callback();
+            // If our callback returned something 'falsy' or we're just looking ahead,
+            // then unconditionally restore us to where we were.
+            if (!result || isLookahead) {
+                pos = savePos;
+                startPos = saveStartPos;
+                tokenPos = saveTokenPos;
+                token = saveToken;
+                tokenValue = saveTokenValue;
+                precedingLineBreak = savePrecedingLineBreak;
+            }
+            return result;
+        }
+        function scanRange(start, length, callback) {
+            var saveEnd = end;
+            var savePos = pos;
+            var saveStartPos = startPos;
+            var saveTokenPos = tokenPos;
+            var saveToken = token;
+            var savePrecedingLineBreak = precedingLineBreak;
+            var saveTokenValue = tokenValue;
+            var saveHasExtendedUnicodeEscape = hasExtendedUnicodeEscape;
+            var saveTokenIsUnterminated = tokenIsUnterminated;
+            setText(text, start, length);
+            var result = callback();
+            end = saveEnd;
+            pos = savePos;
+            startPos = saveStartPos;
+            tokenPos = saveTokenPos;
+            token = saveToken;
+            precedingLineBreak = savePrecedingLineBreak;
+            tokenValue = saveTokenValue;
+            hasExtendedUnicodeEscape = saveHasExtendedUnicodeEscape;
+            tokenIsUnterminated = saveTokenIsUnterminated;
+            return result;
+        }
+        function lookAhead(callback) {
+            return speculationHelper(callback, /*isLookahead*/ true);
+        }
+        function tryScan(callback) {
+            return speculationHelper(callback, /*isLookahead*/ false);
+        }
+        function getText() {
+            return text;
+        }
+        function setText(newText, start, length) {
+            text = newText || "";
+            end = length === undefined ? text.length : start + length;
+            setTextPos(start || 0);
+        }
+        function setOnError(errorCallback) {
+            onError = errorCallback;
+        }
+        function setScriptTarget(scriptTarget) {
+            languageVersion = scriptTarget;
+        }
+        function setLanguageVariant(variant) {
+            languageVariant = variant;
+        }
+        function setTextPos(textPos) {
+            ts.Debug.assert(textPos >= 0);
+            pos = textPos;
+            startPos = textPos;
+            tokenPos = textPos;
+            token = 0 /* Unknown */;
+            precedingLineBreak = false;
+            tokenValue = undefined;
+            hasExtendedUnicodeEscape = false;
+            tokenIsUnterminated = false;
+        }
+    }
+    ts.createScanner = createScanner;
+})(ts || (ts = {}));
+/// <reference path="sys.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    ts.emptyArray = [];
+    ts.emptyMap = ts.createMap();
+    ts.externalHelpersModuleNameText = "tslib";
+    function getDeclarationOfKind(symbol, kind) {
+        var declarations = symbol.declarations;
+        if (declarations) {
+            for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
+                var declaration = declarations_1[_i];
+                if (declaration.kind === kind) {
+                    return declaration;
+                }
+            }
+        }
+        return undefined;
+    }
+    ts.getDeclarationOfKind = getDeclarationOfKind;
+    var stringWriter = createSingleLineStringWriter();
+    function createSingleLineStringWriter() {
+        var str = "";
+        var writeText = function (text) { return str += text; };
+        return {
+            string: function () { return str; },
+            writeKeyword: writeText,
+            writeOperator: writeText,
+            writePunctuation: writeText,
+            writeSpace: writeText,
+            writeStringLiteral: writeText,
+            writeParameter: writeText,
+            writeProperty: writeText,
+            writeSymbol: writeText,
+            // Completely ignore indentation for string writers.  And map newlines to
+            // a single space.
+            writeLine: function () { return str += " "; },
+            increaseIndent: ts.noop,
+            decreaseIndent: ts.noop,
+            clear: function () { return str = ""; },
+            trackSymbol: ts.noop,
+            reportInaccessibleThisError: ts.noop,
+            reportPrivateInBaseOfClassExpression: ts.noop,
+        };
+    }
+    function usingSingleLineStringWriter(action) {
+        var oldString = stringWriter.string();
+        try {
+            action(stringWriter);
+            return stringWriter.string();
+        }
+        finally {
+            stringWriter.clear();
+            stringWriter.writeKeyword(oldString);
+        }
+    }
+    ts.usingSingleLineStringWriter = usingSingleLineStringWriter;
+    function getFullWidth(node) {
+        return node.end - node.pos;
+    }
+    ts.getFullWidth = getFullWidth;
+    function getResolvedModule(sourceFile, moduleNameText) {
+        return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
+    }
+    ts.getResolvedModule = getResolvedModule;
+    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
+        if (!sourceFile.resolvedModules) {
+            sourceFile.resolvedModules = ts.createMap();
+        }
+        sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
+    }
+    ts.setResolvedModule = setResolvedModule;
+    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
+        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
+            sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap();
+        }
+        sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
+    }
+    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
+    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
+        return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
+            oldResolution.extension === newResolution.extension &&
+            oldResolution.resolvedFileName === newResolution.resolvedFileName &&
+            packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
+    }
+    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
+    function packageIdIsEqual(a, b) {
+        return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
+    }
+    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
+        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
+    }
+    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
+    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
+        ts.Debug.assert(names.length === newResolutions.length);
+        for (var i = 0; i < names.length; i++) {
+            var newResolution = newResolutions[i];
+            var oldResolution = oldResolutions && oldResolutions.get(names[i]);
+            var changed = oldResolution
+                ? !newResolution || !comparer(oldResolution, newResolution)
+                : newResolution;
+            if (changed) {
+                return true;
+            }
+        }
+        return false;
+    }
+    ts.hasChangesInResolutions = hasChangesInResolutions;
+    // Returns true if this node contains a parse error anywhere underneath it.
+    function containsParseError(node) {
+        aggregateChildData(node);
+        return (node.flags & 131072 /* ThisNodeOrAnySubNodesHasError */) !== 0;
+    }
+    ts.containsParseError = containsParseError;
+    function aggregateChildData(node) {
+        if (!(node.flags & 262144 /* HasAggregatedChildData */)) {
+            // A node is considered to contain a parse error if:
+            //  a) the parser explicitly marked that it had an error
+            //  b) any of it's children reported that it had an error.
+            var thisNodeOrAnySubNodesHasError = ((node.flags & 32768 /* ThisNodeHasError */) !== 0) ||
+                ts.forEachChild(node, containsParseError);
+            // If so, mark ourselves accordingly.
+            if (thisNodeOrAnySubNodesHasError) {
+                node.flags |= 131072 /* ThisNodeOrAnySubNodesHasError */;
+            }
+            // Also mark that we've propagated the child information to this node.  This way we can
+            // always consult the bit directly on this node without needing to check its children
+            // again.
+            node.flags |= 262144 /* HasAggregatedChildData */;
+        }
+    }
+    function getSourceFileOfNode(node) {
+        while (node && node.kind !== 265 /* SourceFile */) {
+            node = node.parent;
+        }
+        return node;
+    }
+    ts.getSourceFileOfNode = getSourceFileOfNode;
+    function isStatementWithLocals(node) {
+        switch (node.kind) {
+            case 207 /* Block */:
+            case 235 /* CaseBlock */:
+            case 214 /* ForStatement */:
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+                return true;
+        }
+        return false;
+    }
+    ts.isStatementWithLocals = isStatementWithLocals;
+    function getStartPositionOfLine(line, sourceFile) {
+        ts.Debug.assert(line >= 0);
+        return ts.getLineStarts(sourceFile)[line];
+    }
+    ts.getStartPositionOfLine = getStartPositionOfLine;
+    // This is a useful function for debugging purposes.
+    function nodePosToString(node) {
+        var file = getSourceFileOfNode(node);
+        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
+        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
+    }
+    ts.nodePosToString = nodePosToString;
+    function getEndLinePosition(line, sourceFile) {
+        ts.Debug.assert(line >= 0);
+        var lineStarts = ts.getLineStarts(sourceFile);
+        var lineIndex = line;
+        var sourceText = sourceFile.text;
+        if (lineIndex + 1 === lineStarts.length) {
+            // last line - return EOF
+            return sourceText.length - 1;
+        }
+        else {
+            // current line start
+            var start = lineStarts[lineIndex];
+            // take the start position of the next line - 1 = it should be some line break
+            var pos = lineStarts[lineIndex + 1] - 1;
+            ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos)));
+            // walk backwards skipping line breaks, stop the the beginning of current line.
+            // i.e:
+            // <some text>
+            // $ <- end of line for this position should match the start position
+            while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) {
+                pos--;
+            }
+            return pos;
+        }
+    }
+    ts.getEndLinePosition = getEndLinePosition;
+    // Returns true if this node is missing from the actual source code. A 'missing' node is different
+    // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
+    // in the tree), it is definitely missing. However, a node may be defined, but still be
+    // missing.  This happens whenever the parser knows it needs to parse something, but can't
+    // get anything in the source code that it expects at that location. For example:
+    //
+    //          let a: ;
+    //
+    // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
+    // code). So the parser will attempt to parse out a type, and will create an actual node.
+    // However, this node will be 'missing' in the sense that no actual source-code/tokens are
+    // contained within it.
+    function nodeIsMissing(node) {
+        if (node === undefined) {
+            return true;
+        }
+        return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
+    }
+    ts.nodeIsMissing = nodeIsMissing;
+    function nodeIsPresent(node) {
+        return !nodeIsMissing(node);
+    }
+    ts.nodeIsPresent = nodeIsPresent;
+    /**
+     * Determine if the given comment is a triple-slash
+     *
+     * @return true if the comment is a triple-slash comment else false
+     */
+    function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
+        // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
+        // so that we don't end up computing comment string and doing match for all // comments
+        if (text.charCodeAt(commentPos + 1) === 47 /* slash */ &&
+            commentPos + 2 < commentEnd &&
+            text.charCodeAt(commentPos + 2) === 47 /* slash */) {
+            var textSubStr = text.substring(commentPos, commentEnd);
+            return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
+                textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ||
+                textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) ||
+                textSubStr.match(defaultLibReferenceRegEx) ?
+                true : false;
+        }
+        return false;
+    }
+    ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment;
+    function isPinnedComment(text, comment) {
+        return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+            text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
+    }
+    ts.isPinnedComment = isPinnedComment;
+    function getTokenPosOfNode(node, sourceFile, includeJsDoc) {
+        // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
+        // want to skip trivia because this will launch us forward to the next token.
+        if (nodeIsMissing(node)) {
+            return node.pos;
+        }
+        if (ts.isJSDocNode(node)) {
+            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
+        }
+        if (includeJsDoc && ts.hasJSDocNodes(node)) {
+            return getTokenPosOfNode(node.jsDoc[0]);
+        }
+        // For a syntax list, it is possible that one of its children has JSDocComment nodes, while
+        // the syntax list itself considers them as normal trivia. Therefore if we simply skip
+        // trivia for the list, we may have skipped the JSDocComment as well. So we should process its
+        // first child to determine the actual position of its first token.
+        if (node.kind === 286 /* SyntaxList */ && node._children.length > 0) {
+            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc);
+        }
+        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
+    }
+    ts.getTokenPosOfNode = getTokenPosOfNode;
+    function getNonDecoratorTokenPosOfNode(node, sourceFile) {
+        if (nodeIsMissing(node) || !node.decorators) {
+            return getTokenPosOfNode(node, sourceFile);
+        }
+        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
+    }
+    ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
+    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
+        if (includeTrivia === void 0) { includeTrivia = false; }
+        if (nodeIsMissing(node)) {
+            return "";
+        }
+        var text = sourceFile.text;
+        return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
+    }
+    ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
+    function getTextOfNodeFromSourceText(sourceText, node) {
+        if (nodeIsMissing(node)) {
+            return "";
+        }
+        return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
+    }
+    ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
+    function getTextOfNode(node, includeTrivia) {
+        if (includeTrivia === void 0) { includeTrivia = false; }
+        return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
+    }
+    ts.getTextOfNode = getTextOfNode;
+    /**
+     * Note: it is expected that the `nodeArray` and the `node` are within the same file.
+     * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
+     */
+    function indexOfNode(nodeArray, node) {
+        return ts.binarySearch(nodeArray, node, compareNodePos);
+    }
+    ts.indexOfNode = indexOfNode;
+    function compareNodePos(_a, _b) {
+        var aPos = _a.pos;
+        var bPos = _b.pos;
+        return aPos < bPos ? -1 /* LessThan */ : bPos < aPos ? 1 /* GreaterThan */ : 0 /* EqualTo */;
+    }
+    /**
+     * Gets flags that control emit behavior of a node.
+     */
+    function getEmitFlags(node) {
+        var emitNode = node.emitNode;
+        return emitNode && emitNode.flags;
+    }
+    ts.getEmitFlags = getEmitFlags;
+    function getLiteralText(node, sourceFile) {
+        // If we don't need to downlevel and we can reach the original source text using
+        // the node's parent reference, then simply get the text as it was originally written.
+        if (!nodeIsSynthesized(node) && node.parent) {
+            return getSourceTextOfNodeFromSourceFile(sourceFile, node);
+        }
+        var escapeText = getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ? escapeString : escapeNonAsciiString;
+        // If we can't reach the original source text, use the canonical form if it's a number,
+        // or a (possibly escaped) quoted form of the original text if it's string-like.
+        switch (node.kind) {
+            case 9 /* StringLiteral */:
+                if (node.singleQuote) {
+                    return "'" + escapeText(node.text, 39 /* singleQuote */) + "'";
+                }
+                else {
+                    return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"';
+                }
+            case 13 /* NoSubstitutionTemplateLiteral */:
+                return "`" + escapeText(node.text, 96 /* backtick */) + "`";
+            case 14 /* TemplateHead */:
+                return "`" + escapeText(node.text, 96 /* backtick */) + "${";
+            case 15 /* TemplateMiddle */:
+                return "}" + escapeText(node.text, 96 /* backtick */) + "${";
+            case 16 /* TemplateTail */:
+                return "}" + escapeText(node.text, 96 /* backtick */) + "`";
+            case 8 /* NumericLiteral */:
+            case 12 /* RegularExpressionLiteral */:
+                return node.text;
+        }
+        ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
+    }
+    ts.getLiteralText = getLiteralText;
+    function getTextOfConstantValue(value) {
+        return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
+    }
+    ts.getTextOfConstantValue = getTextOfConstantValue;
+    // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
+    function escapeLeadingUnderscores(identifier) {
+        return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier);
+    }
+    ts.escapeLeadingUnderscores = escapeLeadingUnderscores;
+    /**
+     * @deprecated Use `id.escapedText` to get the escaped text of an Identifier.
+     * @param identifier The identifier to escape
+     */
+    function escapeIdentifier(identifier) {
+        return identifier;
+    }
+    ts.escapeIdentifier = escapeIdentifier;
+    // Make an identifier from an external module name by extracting the string after the last "/" and replacing
+    // all non-alphanumeric characters with underscores
+    function makeIdentifierFromModuleName(moduleName) {
+        return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
+    }
+    ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
+    function isBlockOrCatchScoped(declaration) {
+        return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 ||
+            isCatchClauseVariableDeclarationOrBindingElement(declaration);
+    }
+    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
+    function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
+        var node = getRootDeclaration(declaration);
+        return node.kind === 226 /* VariableDeclaration */ && node.parent.kind === 260 /* CatchClause */;
+    }
+    ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement;
+    function isAmbientModule(node) {
+        return node && node.kind === 233 /* ModuleDeclaration */ &&
+            (node.name.kind === 9 /* StringLiteral */ || isGlobalScopeAugmentation(node));
+    }
+    ts.isAmbientModule = isAmbientModule;
+    function isModuleWithStringLiteralName(node) {
+        return ts.isModuleDeclaration(node) && node.name.kind === 9 /* StringLiteral */;
+    }
+    ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName;
+    function isNonGlobalAmbientModule(node) {
+        return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name);
+    }
+    ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule;
+    /** Given a symbol for a module, checks that it is a shorthand ambient module. */
+    function isShorthandAmbientModuleSymbol(moduleSymbol) {
+        return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
+    }
+    ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol;
+    function isShorthandAmbientModule(node) {
+        // The only kind of module that can be missing a body is a shorthand ambient module.
+        return node && node.kind === 233 /* ModuleDeclaration */ && (!node.body);
+    }
+    function isBlockScopedContainerTopLevel(node) {
+        return node.kind === 265 /* SourceFile */ ||
+            node.kind === 233 /* ModuleDeclaration */ ||
+            ts.isFunctionLike(node);
+    }
+    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
+    function isGlobalScopeAugmentation(module) {
+        return !!(module.flags & 512 /* GlobalAugmentation */);
+    }
+    ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation;
+    function isExternalModuleAugmentation(node) {
+        // external module augmentation is a ambient module declaration that is either:
+        // - defined in the top level scope and source file is an external module
+        // - defined inside ambient module declaration located in the top level scope and source file not an external module
+        if (!node || !isAmbientModule(node)) {
+            return false;
+        }
+        switch (node.parent.kind) {
+            case 265 /* SourceFile */:
+                return ts.isExternalModule(node.parent);
+            case 234 /* ModuleBlock */:
+                return isAmbientModule(node.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
+        }
+        return false;
+    }
+    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
+    function isEffectiveExternalModule(node, compilerOptions) {
+        return ts.isExternalModule(node) || compilerOptions.isolatedModules;
+    }
+    ts.isEffectiveExternalModule = isEffectiveExternalModule;
+    /* @internal */
+    function isBlockScope(node, parentNode) {
+        switch (node.kind) {
+            case 265 /* SourceFile */:
+            case 235 /* CaseBlock */:
+            case 260 /* CatchClause */:
+            case 233 /* ModuleDeclaration */:
+            case 214 /* ForStatement */:
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+            case 152 /* Constructor */:
+            case 151 /* MethodDeclaration */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+                return true;
+            case 207 /* Block */:
+                // function block is not considered block-scope container
+                // see comment in binder.ts: bind(...), case for SyntaxKind.Block
+                return parentNode && !ts.isFunctionLike(parentNode);
+        }
+        return false;
+    }
+    ts.isBlockScope = isBlockScope;
+    function isDeclarationWithTypeParameters(node) {
+        switch (node.kind) {
+            case 155 /* CallSignature */:
+            case 156 /* ConstructSignature */:
+            case 150 /* MethodSignature */:
+            case 157 /* IndexSignature */:
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+            case 273 /* JSDocFunctionType */:
+            case 229 /* ClassDeclaration */:
+            case 199 /* ClassExpression */:
+            case 230 /* InterfaceDeclaration */:
+            case 231 /* TypeAliasDeclaration */:
+            case 282 /* JSDocTemplateTag */:
+            case 228 /* FunctionDeclaration */:
+            case 151 /* MethodDeclaration */:
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+                return true;
+            default:
+                ts.assertTypeIsNever(node);
+                return false;
+        }
+    }
+    ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters;
+    /* @internal */
+    function isAnyImportSyntax(node) {
+        switch (node.kind) {
+            case 238 /* ImportDeclaration */:
+            case 237 /* ImportEqualsDeclaration */:
+                return true;
+            default:
+                return false;
+        }
+    }
+    ts.isAnyImportSyntax = isAnyImportSyntax;
+    // Gets the nearest enclosing block scope container that has the provided node
+    // as a descendant, that is not the provided node.
+    function getEnclosingBlockScopeContainer(node) {
+        var current = node.parent;
+        while (current) {
+            if (isBlockScope(current, current.parent)) {
+                return current;
+            }
+            current = current.parent;
+        }
+    }
+    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
+    // Return display name of an identifier
+    // Computed property names will just be emitted as "[<expr>]", where <expr> is the source
+    // text of the expression in the computed property.
+    function declarationNameToString(name) {
+        return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
+    }
+    ts.declarationNameToString = declarationNameToString;
+    function getNameFromIndexInfo(info) {
+        return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
+    }
+    ts.getNameFromIndexInfo = getNameFromIndexInfo;
+    function getTextOfPropertyName(name) {
+        switch (name.kind) {
+            case 71 /* Identifier */:
+                return name.escapedText;
+            case 9 /* StringLiteral */:
+            case 8 /* NumericLiteral */:
+                return escapeLeadingUnderscores(name.text);
+            case 144 /* ComputedPropertyName */:
+                if (isStringOrNumericLiteral(name.expression)) {
+                    return escapeLeadingUnderscores(name.expression.text);
+                }
+        }
+        return undefined;
+    }
+    ts.getTextOfPropertyName = getTextOfPropertyName;
+    function entityNameToString(name) {
+        switch (name.kind) {
+            case 71 /* Identifier */:
+                return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name);
+            case 143 /* QualifiedName */:
+                return entityNameToString(name.left) + "." + entityNameToString(name.right);
+            case 179 /* PropertyAccessExpression */:
+                return entityNameToString(name.expression) + "." + entityNameToString(name.name);
+        }
+    }
+    ts.entityNameToString = entityNameToString;
+    function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
+        var sourceFile = getSourceFileOfNode(node);
+        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
+    }
+    ts.createDiagnosticForNode = createDiagnosticForNode;
+    function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2) {
+        var span = getErrorSpanForNode(sourceFile, node);
+        return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
+    }
+    ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile;
+    function createDiagnosticForNodeFromMessageChain(node, messageChain) {
+        var sourceFile = getSourceFileOfNode(node);
+        var span = getErrorSpanForNode(sourceFile, node);
+        return {
+            file: sourceFile,
+            start: span.start,
+            length: span.length,
+            code: messageChain.code,
+            category: messageChain.category,
+            messageText: messageChain.next ? messageChain : messageChain.messageText
+        };
+    }
+    ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
+    function getSpanOfTokenAtPosition(sourceFile, pos) {
+        var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
+        scanner.scan();
+        var start = scanner.getTokenPos();
+        return ts.createTextSpanFromBounds(start, scanner.getTextPos());
+    }
+    ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
+    function getErrorSpanForArrowFunction(sourceFile, node) {
+        var pos = ts.skipTrivia(sourceFile.text, node.pos);
+        if (node.body && node.body.kind === 207 /* Block */) {
+            var startLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.pos).line;
+            var endLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.end).line;
+            if (startLine < endLine) {
+                // The arrow function spans multiple lines,
+                // make the error span be the first line, inclusive.
+                return ts.createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
+            }
+        }
+        return ts.createTextSpanFromBounds(pos, node.end);
+    }
+    function getErrorSpanForNode(sourceFile, node) {
+        var errorNode = node;
+        switch (node.kind) {
+            case 265 /* SourceFile */:
+                var pos_1 = ts.skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
+                if (pos_1 === sourceFile.text.length) {
+                    // file is empty - return span for the beginning of the file
+                    return ts.createTextSpan(0, 0);
+                }
+                return getSpanOfTokenAtPosition(sourceFile, pos_1);
+            // This list is a work in progress. Add missing node kinds to improve their error
+            // spans.
+            case 226 /* VariableDeclaration */:
+            case 176 /* BindingElement */:
+            case 229 /* ClassDeclaration */:
+            case 199 /* ClassExpression */:
+            case 230 /* InterfaceDeclaration */:
+            case 233 /* ModuleDeclaration */:
+            case 232 /* EnumDeclaration */:
+            case 264 /* EnumMember */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 151 /* MethodDeclaration */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 231 /* TypeAliasDeclaration */:
+                errorNode = node.name;
+                break;
+            case 187 /* ArrowFunction */:
+                return getErrorSpanForArrowFunction(sourceFile, node);
+        }
+        if (errorNode === undefined) {
+            // If we don't have a better node, then just set the error on the first token of
+            // construct.
+            return getSpanOfTokenAtPosition(sourceFile, node.pos);
+        }
+        var pos = nodeIsMissing(errorNode)
+            ? errorNode.pos
+            : ts.skipTrivia(sourceFile.text, errorNode.pos);
+        return ts.createTextSpanFromBounds(pos, errorNode.end);
+    }
+    ts.getErrorSpanForNode = getErrorSpanForNode;
+    function isExternalOrCommonJsModule(file) {
+        return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+    }
+    ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
+    function isConstEnumDeclaration(node) {
+        return node.kind === 232 /* EnumDeclaration */ && isConst(node);
+    }
+    ts.isConstEnumDeclaration = isConstEnumDeclaration;
+    function isConst(node) {
+        return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */)
+            || !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */);
+    }
+    ts.isConst = isConst;
+    function isLet(node) {
+        return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */);
+    }
+    ts.isLet = isLet;
+    function isSuperCall(n) {
+        return n.kind === 181 /* CallExpression */ && n.expression.kind === 97 /* SuperKeyword */;
+    }
+    ts.isSuperCall = isSuperCall;
+    function isImportCall(n) {
+        return n.kind === 181 /* CallExpression */ && n.expression.kind === 91 /* ImportKeyword */;
+    }
+    ts.isImportCall = isImportCall;
+    function isPrologueDirective(node) {
+        return node.kind === 210 /* ExpressionStatement */
+            && node.expression.kind === 9 /* StringLiteral */;
+    }
+    ts.isPrologueDirective = isPrologueDirective;
+    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
+        return node.kind !== 10 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
+    }
+    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
+    function getJSDocCommentRanges(node, text) {
+        var commentRanges = (node.kind === 146 /* Parameter */ ||
+            node.kind === 145 /* TypeParameter */ ||
+            node.kind === 186 /* FunctionExpression */ ||
+            node.kind === 187 /* ArrowFunction */ ||
+            node.kind === 185 /* ParenthesizedExpression */) ?
+            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
+            ts.getLeadingCommentRanges(text, node.pos);
+        // True if the comment starts with '/**' but not if it is '/**/'
+        return ts.filter(commentRanges, function (comment) {
+            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
+                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
+        });
+    }
+    ts.getJSDocCommentRanges = getJSDocCommentRanges;
+    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
+    var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
+    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
+    var defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
+    function isPartOfTypeNode(node) {
+        if (158 /* FirstTypeNode */ <= node.kind && node.kind <= 173 /* LastTypeNode */) {
+            return true;
+        }
+        switch (node.kind) {
+            case 119 /* AnyKeyword */:
+            case 133 /* NumberKeyword */:
+            case 136 /* StringKeyword */:
+            case 122 /* BooleanKeyword */:
+            case 137 /* SymbolKeyword */:
+            case 139 /* UndefinedKeyword */:
+            case 130 /* NeverKeyword */:
+                return true;
+            case 105 /* VoidKeyword */:
+                return node.parent.kind !== 190 /* VoidExpression */;
+            case 201 /* ExpressionWithTypeArguments */:
+                return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
+            // Identifiers and qualified names may be type nodes, depending on their context. Climb
+            // above them to find the lowest container
+            case 71 /* Identifier */:
+                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
+                if (node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node) {
+                    node = node.parent;
+                }
+                else if (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node) {
+                    node = node.parent;
+                }
+                // At this point, node is either a qualified name or an identifier
+                ts.Debug.assert(node.kind === 71 /* Identifier */ || node.kind === 143 /* QualifiedName */ || node.kind === 179 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
+            // falls through
+            case 143 /* QualifiedName */:
+            case 179 /* PropertyAccessExpression */:
+            case 99 /* ThisKeyword */:
+                var parent = node.parent;
+                if (parent.kind === 162 /* TypeQuery */) {
+                    return false;
+                }
+                // Do not recursively call isPartOfTypeNode on the parent. In the example:
+                //
+                //     let a: A.B.C;
+                //
+                // Calling isPartOfTypeNode would consider the qualified name A.B a type node.
+                // Only C and A.B.C are type nodes.
+                if (158 /* FirstTypeNode */ <= parent.kind && parent.kind <= 173 /* LastTypeNode */) {
+                    return true;
+                }
+                switch (parent.kind) {
+                    case 201 /* ExpressionWithTypeArguments */:
+                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
+                    case 145 /* TypeParameter */:
+                        return node === parent.constraint;
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                    case 146 /* Parameter */:
+                    case 226 /* VariableDeclaration */:
+                        return node === parent.type;
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                    case 152 /* Constructor */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        return node === parent.type;
+                    case 155 /* CallSignature */:
+                    case 156 /* ConstructSignature */:
+                    case 157 /* IndexSignature */:
+                        return node === parent.type;
+                    case 184 /* TypeAssertionExpression */:
+                        return node === parent.type;
+                    case 181 /* CallExpression */:
+                    case 182 /* NewExpression */:
+                        return parent.typeArguments && ts.indexOf(parent.typeArguments, node) >= 0;
+                    case 183 /* TaggedTemplateExpression */:
+                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
+                        return false;
+                }
+        }
+        return false;
+    }
+    ts.isPartOfTypeNode = isPartOfTypeNode;
+    function isChildOfNodeWithKind(node, kind) {
+        while (node) {
+            if (node.kind === kind) {
+                return true;
+            }
+            node = node.parent;
+        }
+        return false;
+    }
+    ts.isChildOfNodeWithKind = isChildOfNodeWithKind;
+    // Warning: This has the same semantics as the forEach family of functions,
+    //          in that traversal terminates in the event that 'visitor' supplies a truthy value.
+    function forEachReturnStatement(body, visitor) {
+        return traverse(body);
+        function traverse(node) {
+            switch (node.kind) {
+                case 219 /* ReturnStatement */:
+                    return visitor(node);
+                case 235 /* CaseBlock */:
+                case 207 /* Block */:
+                case 211 /* IfStatement */:
+                case 212 /* DoStatement */:
+                case 213 /* WhileStatement */:
+                case 214 /* ForStatement */:
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                case 220 /* WithStatement */:
+                case 221 /* SwitchStatement */:
+                case 257 /* CaseClause */:
+                case 258 /* DefaultClause */:
+                case 222 /* LabeledStatement */:
+                case 224 /* TryStatement */:
+                case 260 /* CatchClause */:
+                    return ts.forEachChild(node, traverse);
+            }
+        }
+    }
+    ts.forEachReturnStatement = forEachReturnStatement;
+    function forEachYieldExpression(body, visitor) {
+        return traverse(body);
+        function traverse(node) {
+            switch (node.kind) {
+                case 197 /* YieldExpression */:
+                    visitor(node);
+                    var operand = node.expression;
+                    if (operand) {
+                        traverse(operand);
+                    }
+                    return;
+                case 232 /* EnumDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                case 233 /* ModuleDeclaration */:
+                case 231 /* TypeAliasDeclaration */:
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                    // These are not allowed inside a generator now, but eventually they may be allowed
+                    // as local types. Regardless, any yield statements contained within them should be
+                    // skipped in this traversal.
+                    return;
+                default:
+                    if (ts.isFunctionLike(node)) {
+                        var name = node.name;
+                        if (name && name.kind === 144 /* ComputedPropertyName */) {
+                            // Note that we will not include methods/accessors of a class because they would require
+                            // first descending into the class. This is by design.
+                            traverse(name.expression);
+                            return;
+                        }
+                    }
+                    else if (!isPartOfTypeNode(node)) {
+                        // This is the general case, which should include mostly expressions and statements.
+                        // Also includes NodeArrays.
+                        ts.forEachChild(node, traverse);
+                    }
+            }
+        }
+    }
+    ts.forEachYieldExpression = forEachYieldExpression;
+    /**
+     * Gets the most likely element type for a TypeNode. This is not an exhaustive test
+     * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
+     *
+     * @param node The type node.
+     */
+    function getRestParameterElementType(node) {
+        if (node && node.kind === 164 /* ArrayType */) {
+            return node.elementType;
+        }
+        else if (node && node.kind === 159 /* TypeReference */) {
+            return ts.singleOrUndefined(node.typeArguments);
+        }
+        else {
+            return undefined;
+        }
+    }
+    ts.getRestParameterElementType = getRestParameterElementType;
+    function isVariableLike(node) {
+        if (node) {
+            switch (node.kind) {
+                case 176 /* BindingElement */:
+                case 264 /* EnumMember */:
+                case 146 /* Parameter */:
+                case 261 /* PropertyAssignment */:
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                case 262 /* ShorthandPropertyAssignment */:
+                case 226 /* VariableDeclaration */:
+                    return true;
+            }
+        }
+        return false;
+    }
+    ts.isVariableLike = isVariableLike;
+    function introducesArgumentsExoticObject(node) {
+        switch (node.kind) {
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+                return true;
+        }
+        return false;
+    }
+    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
+    function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) {
+        while (true) {
+            if (beforeUnwrapLabelCallback) {
+                beforeUnwrapLabelCallback(node);
+            }
+            if (node.statement.kind !== 222 /* LabeledStatement */) {
+                return node.statement;
+            }
+            node = node.statement;
+        }
+    }
+    ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel;
+    function isFunctionBlock(node) {
+        return node && node.kind === 207 /* Block */ && ts.isFunctionLike(node.parent);
+    }
+    ts.isFunctionBlock = isFunctionBlock;
+    function isObjectLiteralMethod(node) {
+        return node && node.kind === 151 /* MethodDeclaration */ && node.parent.kind === 178 /* ObjectLiteralExpression */;
+    }
+    ts.isObjectLiteralMethod = isObjectLiteralMethod;
+    function isObjectLiteralOrClassExpressionMethod(node) {
+        return node.kind === 151 /* MethodDeclaration */ &&
+            (node.parent.kind === 178 /* ObjectLiteralExpression */ ||
+                node.parent.kind === 199 /* ClassExpression */);
+    }
+    ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod;
+    function isIdentifierTypePredicate(predicate) {
+        return predicate && predicate.kind === 1 /* Identifier */;
+    }
+    ts.isIdentifierTypePredicate = isIdentifierTypePredicate;
+    function isThisTypePredicate(predicate) {
+        return predicate && predicate.kind === 0 /* This */;
+    }
+    ts.isThisTypePredicate = isThisTypePredicate;
+    function getPropertyAssignment(objectLiteral, key, key2) {
+        return ts.filter(objectLiteral.properties, function (property) {
+            if (property.kind === 261 /* PropertyAssignment */) {
+                var propName = getTextOfPropertyName(property.name);
+                return key === propName || (key2 && key2 === propName);
+            }
+        });
+    }
+    ts.getPropertyAssignment = getPropertyAssignment;
+    function getContainingFunction(node) {
+        return ts.findAncestor(node.parent, ts.isFunctionLike);
+    }
+    ts.getContainingFunction = getContainingFunction;
+    function getContainingClass(node) {
+        return ts.findAncestor(node.parent, ts.isClassLike);
+    }
+    ts.getContainingClass = getContainingClass;
+    function getThisContainer(node, includeArrowFunctions) {
+        while (true) {
+            node = node.parent;
+            if (!node) {
+                return undefined;
+            }
+            switch (node.kind) {
+                case 144 /* ComputedPropertyName */:
+                    // If the grandparent node is an object literal (as opposed to a class),
+                    // then the computed property is not a 'this' container.
+                    // A computed property name in a class needs to be a this container
+                    // so that we can error on it.
+                    if (ts.isClassLike(node.parent.parent)) {
+                        return node;
+                    }
+                    // If this is a computed property, then the parent should not
+                    // make it a this container. The parent might be a property
+                    // in an object literal, like a method or accessor. But in order for
+                    // such a parent to be a this container, the reference must be in
+                    // the *body* of the container.
+                    node = node.parent;
+                    break;
+                case 147 /* Decorator */:
+                    // Decorators are always applied outside of the body of a class or method.
+                    if (node.parent.kind === 146 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
+                        // If the decorator's parent is a Parameter, we resolve the this container from
+                        // the grandparent class declaration.
+                        node = node.parent.parent;
+                    }
+                    else if (ts.isClassElement(node.parent)) {
+                        // If the decorator's parent is a class element, we resolve the 'this' container
+                        // from the parent class declaration.
+                        node = node.parent;
+                    }
+                    break;
+                case 187 /* ArrowFunction */:
+                    if (!includeArrowFunctions) {
+                        continue;
+                    }
+                // falls through
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 233 /* ModuleDeclaration */:
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 152 /* Constructor */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 155 /* CallSignature */:
+                case 156 /* ConstructSignature */:
+                case 157 /* IndexSignature */:
+                case 232 /* EnumDeclaration */:
+                case 265 /* SourceFile */:
+                    return node;
+            }
+        }
+    }
+    ts.getThisContainer = getThisContainer;
+    function getNewTargetContainer(node) {
+        var container = getThisContainer(node, /*includeArrowFunctions*/ false);
+        if (container) {
+            switch (container.kind) {
+                case 152 /* Constructor */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                    return container;
+            }
+        }
+        return undefined;
+    }
+    ts.getNewTargetContainer = getNewTargetContainer;
+    /**
+     * Given an super call/property node, returns the closest node where
+     * - a super call/property access is legal in the node and not legal in the parent node the node.
+     *   i.e. super call is legal in constructor but not legal in the class body.
+     * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
+     * - a super call/property is definitely illegal in the container (but might be legal in some subnode)
+     *   i.e. super property access is illegal in function declaration but can be legal in the statement list
+     */
+    function getSuperContainer(node, stopOnFunctions) {
+        while (true) {
+            node = node.parent;
+            if (!node) {
+                return node;
+            }
+            switch (node.kind) {
+                case 144 /* ComputedPropertyName */:
+                    node = node.parent;
+                    break;
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    if (!stopOnFunctions) {
+                        continue;
+                    }
+                // falls through
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 152 /* Constructor */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return node;
+                case 147 /* Decorator */:
+                    // Decorators are always applied outside of the body of a class or method.
+                    if (node.parent.kind === 146 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
+                        // If the decorator's parent is a Parameter, we resolve the this container from
+                        // the grandparent class declaration.
+                        node = node.parent.parent;
+                    }
+                    else if (ts.isClassElement(node.parent)) {
+                        // If the decorator's parent is a class element, we resolve the 'this' container
+                        // from the parent class declaration.
+                        node = node.parent;
+                    }
+                    break;
+            }
+        }
+    }
+    ts.getSuperContainer = getSuperContainer;
+    function getImmediatelyInvokedFunctionExpression(func) {
+        if (func.kind === 186 /* FunctionExpression */ || func.kind === 187 /* ArrowFunction */) {
+            var prev = func;
+            var parent = func.parent;
+            while (parent.kind === 185 /* ParenthesizedExpression */) {
+                prev = parent;
+                parent = parent.parent;
+            }
+            if (parent.kind === 181 /* CallExpression */ && parent.expression === prev) {
+                return parent;
+            }
+        }
+    }
+    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
+    /**
+     * Determines whether a node is a property or element access expression for super.
+     */
+    function isSuperProperty(node) {
+        var kind = node.kind;
+        return (kind === 179 /* PropertyAccessExpression */ || kind === 180 /* ElementAccessExpression */)
+            && node.expression.kind === 97 /* SuperKeyword */;
+    }
+    ts.isSuperProperty = isSuperProperty;
+    function getEntityNameFromTypeNode(node) {
+        switch (node.kind) {
+            case 159 /* TypeReference */:
+                return node.typeName;
+            case 201 /* ExpressionWithTypeArguments */:
+                return isEntityNameExpression(node.expression)
+                    ? node.expression
+                    : undefined;
+            case 71 /* Identifier */:
+            case 143 /* QualifiedName */:
+                return node;
+        }
+        return undefined;
+    }
+    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
+    function getInvokedExpression(node) {
+        if (node.kind === 183 /* TaggedTemplateExpression */) {
+            return node.tag;
+        }
+        else if (ts.isJsxOpeningLikeElement(node)) {
+            return node.tagName;
+        }
+        // Will either be a CallExpression, NewExpression, or Decorator.
+        return node.expression;
+    }
+    ts.getInvokedExpression = getInvokedExpression;
+    function nodeCanBeDecorated(node) {
+        switch (node.kind) {
+            case 229 /* ClassDeclaration */:
+                // classes are valid targets
+                return true;
+            case 149 /* PropertyDeclaration */:
+                // property declarations are valid if their parent is a class declaration.
+                return node.parent.kind === 229 /* ClassDeclaration */;
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 151 /* MethodDeclaration */:
+                // if this method has a body and its parent is a class declaration, this is a valid target.
+                return node.body !== undefined
+                    && node.parent.kind === 229 /* ClassDeclaration */;
+            case 146 /* Parameter */:
+                // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
+                return node.parent.body !== undefined
+                    && (node.parent.kind === 152 /* Constructor */
+                        || node.parent.kind === 151 /* MethodDeclaration */
+                        || node.parent.kind === 154 /* SetAccessor */)
+                    && node.parent.parent.kind === 229 /* ClassDeclaration */;
+        }
+        return false;
+    }
+    ts.nodeCanBeDecorated = nodeCanBeDecorated;
+    function nodeIsDecorated(node) {
+        return node.decorators !== undefined
+            && nodeCanBeDecorated(node);
+    }
+    ts.nodeIsDecorated = nodeIsDecorated;
+    function nodeOrChildIsDecorated(node) {
+        return nodeIsDecorated(node) || childIsDecorated(node);
+    }
+    ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
+    function childIsDecorated(node) {
+        switch (node.kind) {
+            case 229 /* ClassDeclaration */:
+                return ts.forEach(node.members, nodeOrChildIsDecorated);
+            case 151 /* MethodDeclaration */:
+            case 154 /* SetAccessor */:
+                return ts.forEach(node.parameters, nodeIsDecorated);
+        }
+    }
+    ts.childIsDecorated = childIsDecorated;
+    function isJSXTagName(node) {
+        var parent = node.parent;
+        if (parent.kind === 251 /* JsxOpeningElement */ ||
+            parent.kind === 250 /* JsxSelfClosingElement */ ||
+            parent.kind === 252 /* JsxClosingElement */) {
+            return parent.tagName === node;
+        }
+        return false;
+    }
+    ts.isJSXTagName = isJSXTagName;
+    function isPartOfExpression(node) {
+        switch (node.kind) {
+            case 97 /* SuperKeyword */:
+            case 95 /* NullKeyword */:
+            case 101 /* TrueKeyword */:
+            case 86 /* FalseKeyword */:
+            case 12 /* RegularExpressionLiteral */:
+            case 177 /* ArrayLiteralExpression */:
+            case 178 /* ObjectLiteralExpression */:
+            case 179 /* PropertyAccessExpression */:
+            case 180 /* ElementAccessExpression */:
+            case 181 /* CallExpression */:
+            case 182 /* NewExpression */:
+            case 183 /* TaggedTemplateExpression */:
+            case 202 /* AsExpression */:
+            case 184 /* TypeAssertionExpression */:
+            case 203 /* NonNullExpression */:
+            case 185 /* ParenthesizedExpression */:
+            case 186 /* FunctionExpression */:
+            case 199 /* ClassExpression */:
+            case 187 /* ArrowFunction */:
+            case 190 /* VoidExpression */:
+            case 188 /* DeleteExpression */:
+            case 189 /* TypeOfExpression */:
+            case 192 /* PrefixUnaryExpression */:
+            case 193 /* PostfixUnaryExpression */:
+            case 194 /* BinaryExpression */:
+            case 195 /* ConditionalExpression */:
+            case 198 /* SpreadElement */:
+            case 196 /* TemplateExpression */:
+            case 13 /* NoSubstitutionTemplateLiteral */:
+            case 200 /* OmittedExpression */:
+            case 249 /* JsxElement */:
+            case 250 /* JsxSelfClosingElement */:
+            case 197 /* YieldExpression */:
+            case 191 /* AwaitExpression */:
+            case 204 /* MetaProperty */:
+                return true;
+            case 143 /* QualifiedName */:
+                while (node.parent.kind === 143 /* QualifiedName */) {
+                    node = node.parent;
+                }
+                return node.parent.kind === 162 /* TypeQuery */ || isJSXTagName(node);
+            case 71 /* Identifier */:
+                if (node.parent.kind === 162 /* TypeQuery */ || isJSXTagName(node)) {
+                    return true;
+                }
+            // falls through
+            case 8 /* NumericLiteral */:
+            case 9 /* StringLiteral */:
+            case 99 /* ThisKeyword */:
+                return isInExpressionContext(node);
+            default:
+                return false;
+        }
+    }
+    ts.isPartOfExpression = isPartOfExpression;
+    function isInExpressionContext(node) {
+        var parent = node.parent;
+        switch (parent.kind) {
+            case 226 /* VariableDeclaration */:
+            case 146 /* Parameter */:
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+            case 264 /* EnumMember */:
+            case 261 /* PropertyAssignment */:
+            case 176 /* BindingElement */:
+                return parent.initializer === node;
+            case 210 /* ExpressionStatement */:
+            case 211 /* IfStatement */:
+            case 212 /* DoStatement */:
+            case 213 /* WhileStatement */:
+            case 219 /* ReturnStatement */:
+            case 220 /* WithStatement */:
+            case 221 /* SwitchStatement */:
+            case 257 /* CaseClause */:
+            case 223 /* ThrowStatement */:
+                return parent.expression === node;
+            case 214 /* ForStatement */:
+                var forStatement = parent;
+                return (forStatement.initializer === node && forStatement.initializer.kind !== 227 /* VariableDeclarationList */) ||
+                    forStatement.condition === node ||
+                    forStatement.incrementor === node;
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+                var forInStatement = parent;
+                return (forInStatement.initializer === node && forInStatement.initializer.kind !== 227 /* VariableDeclarationList */) ||
+                    forInStatement.expression === node;
+            case 184 /* TypeAssertionExpression */:
+            case 202 /* AsExpression */:
+                return node === parent.expression;
+            case 205 /* TemplateSpan */:
+                return node === parent.expression;
+            case 144 /* ComputedPropertyName */:
+                return node === parent.expression;
+            case 147 /* Decorator */:
+            case 256 /* JsxExpression */:
+            case 255 /* JsxSpreadAttribute */:
+            case 263 /* SpreadAssignment */:
+                return true;
+            case 201 /* ExpressionWithTypeArguments */:
+                return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
+            default:
+                return isPartOfExpression(parent);
+        }
+    }
+    ts.isInExpressionContext = isInExpressionContext;
+    function isExternalModuleImportEqualsDeclaration(node) {
+        return node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 248 /* ExternalModuleReference */;
+    }
+    ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
+    function getExternalModuleImportEqualsDeclarationExpression(node) {
+        ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
+        return node.moduleReference.expression;
+    }
+    ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
+    function isInternalModuleImportEqualsDeclaration(node) {
+        return node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 248 /* ExternalModuleReference */;
+    }
+    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
+    function isSourceFileJavaScript(file) {
+        return isInJavaScriptFile(file);
+    }
+    ts.isSourceFileJavaScript = isSourceFileJavaScript;
+    function isInJavaScriptFile(node) {
+        return node && !!(node.flags & 65536 /* JavaScriptFile */);
+    }
+    ts.isInJavaScriptFile = isInJavaScriptFile;
+    function isInJSDoc(node) {
+        return node && !!(node.flags & 1048576 /* JSDoc */);
+    }
+    ts.isInJSDoc = isInJSDoc;
+    function isJSDocIndexSignature(node) {
+        return ts.isTypeReferenceNode(node) &&
+            ts.isIdentifier(node.typeName) &&
+            node.typeName.escapedText === "Object" &&
+            node.typeArguments && node.typeArguments.length === 2 &&
+            (node.typeArguments[0].kind === 136 /* StringKeyword */ || node.typeArguments[0].kind === 133 /* NumberKeyword */);
+    }
+    ts.isJSDocIndexSignature = isJSDocIndexSignature;
+    /**
+     * Returns true if the node is a CallExpression to the identifier 'require' with
+     * exactly one argument (of the form 'require("name")').
+     * This function does not test if the node is in a JavaScript file or not.
+     */
+    function isRequireCall(callExpression, checkArgumentIsStringLiteral) {
+        if (callExpression.kind !== 181 /* CallExpression */) {
+            return false;
+        }
+        var _a = callExpression, expression = _a.expression, args = _a.arguments;
+        if (expression.kind !== 71 /* Identifier */ || expression.escapedText !== "require") {
+            return false;
+        }
+        if (args.length !== 1) {
+            return false;
+        }
+        var arg = args[0];
+        return !checkArgumentIsStringLiteral || arg.kind === 9 /* StringLiteral */ || arg.kind === 13 /* NoSubstitutionTemplateLiteral */;
+    }
+    ts.isRequireCall = isRequireCall;
+    function isSingleOrDoubleQuote(charCode) {
+        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
+    }
+    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
+    function isStringDoubleQuoted(string, sourceFile) {
+        return getSourceTextOfNodeFromSourceFile(sourceFile, string).charCodeAt(0) === 34 /* doubleQuote */;
+    }
+    ts.isStringDoubleQuoted = isStringDoubleQuoted;
+    /**
+     * Returns true if the node is a variable declaration whose initializer is a function expression.
+     * This function does not test if the node is in a JavaScript file or not.
+     */
+    function isDeclarationOfFunctionOrClassExpression(s) {
+        if (s.valueDeclaration && s.valueDeclaration.kind === 226 /* VariableDeclaration */) {
+            var declaration = s.valueDeclaration;
+            return declaration.initializer && (declaration.initializer.kind === 186 /* FunctionExpression */ || declaration.initializer.kind === 199 /* ClassExpression */);
+        }
+        return false;
+    }
+    ts.isDeclarationOfFunctionOrClassExpression = isDeclarationOfFunctionOrClassExpression;
+    function getRightMostAssignedExpression(node) {
+        while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
+            node = node.right;
+        }
+        return node;
+    }
+    ts.getRightMostAssignedExpression = getRightMostAssignedExpression;
+    function isExportsIdentifier(node) {
+        return ts.isIdentifier(node) && node.escapedText === "exports";
+    }
+    ts.isExportsIdentifier = isExportsIdentifier;
+    function isModuleExportsPropertyAccessExpression(node) {
+        return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === "module" && node.name.escapedText === "exports";
+    }
+    ts.isModuleExportsPropertyAccessExpression = isModuleExportsPropertyAccessExpression;
+    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
+    /// assignments we treat as special in the binder
+    function getSpecialPropertyAssignmentKind(expr) {
+        if (!isInJavaScriptFile(expr)) {
+            return 0 /* None */;
+        }
+        if (expr.operatorToken.kind !== 58 /* EqualsToken */ || expr.left.kind !== 179 /* PropertyAccessExpression */) {
+            return 0 /* None */;
+        }
+        var lhs = expr.left;
+        if (lhs.expression.kind === 71 /* Identifier */) {
+            var lhsId = lhs.expression;
+            if (lhsId.escapedText === "exports") {
+                // exports.name = expr
+                return 1 /* ExportsProperty */;
+            }
+            else if (lhsId.escapedText === "module" && lhs.name.escapedText === "exports") {
+                // module.exports = expr
+                return 2 /* ModuleExports */;
+            }
+            else {
+                // F.x = expr
+                return 5 /* Property */;
+            }
+        }
+        else if (lhs.expression.kind === 99 /* ThisKeyword */) {
+            return 4 /* ThisProperty */;
+        }
+        else if (lhs.expression.kind === 179 /* PropertyAccessExpression */) {
+            // chained dot, e.g. x.y.z = expr; this var is the 'x.y' part
+            var innerPropertyAccess = lhs.expression;
+            if (innerPropertyAccess.expression.kind === 71 /* Identifier */) {
+                // module.exports.name = expr
+                var innerPropertyAccessIdentifier = innerPropertyAccess.expression;
+                if (innerPropertyAccessIdentifier.escapedText === "module" && innerPropertyAccess.name.escapedText === "exports") {
+                    return 1 /* ExportsProperty */;
+                }
+                if (innerPropertyAccess.name.escapedText === "prototype") {
+                    return 3 /* PrototypeProperty */;
+                }
+            }
+        }
+        return 0 /* None */;
+    }
+    ts.getSpecialPropertyAssignmentKind = getSpecialPropertyAssignmentKind;
+    function getExternalModuleName(node) {
+        if (node.kind === 238 /* ImportDeclaration */) {
+            return node.moduleSpecifier;
+        }
+        if (node.kind === 237 /* ImportEqualsDeclaration */) {
+            var reference = node.moduleReference;
+            if (reference.kind === 248 /* ExternalModuleReference */) {
+                return reference.expression;
+            }
+        }
+        if (node.kind === 244 /* ExportDeclaration */) {
+            return node.moduleSpecifier;
+        }
+        if (isModuleWithStringLiteralName(node)) {
+            return node.name;
+        }
+    }
+    ts.getExternalModuleName = getExternalModuleName;
+    function getNamespaceDeclarationNode(node) {
+        if (node.kind === 237 /* ImportEqualsDeclaration */) {
+            return node;
+        }
+        var importClause = node.importClause;
+        if (importClause && importClause.namedBindings && importClause.namedBindings.kind === 240 /* NamespaceImport */) {
+            return importClause.namedBindings;
+        }
+    }
+    ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode;
+    function isDefaultImport(node) {
+        return node.kind === 238 /* ImportDeclaration */
+            && node.importClause
+            && !!node.importClause.name;
+    }
+    ts.isDefaultImport = isDefaultImport;
+    function hasQuestionToken(node) {
+        if (node) {
+            switch (node.kind) {
+                case 146 /* Parameter */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 262 /* ShorthandPropertyAssignment */:
+                case 261 /* PropertyAssignment */:
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    return node.questionToken !== undefined;
+            }
+        }
+        return false;
+    }
+    ts.hasQuestionToken = hasQuestionToken;
+    function isJSDocConstructSignature(node) {
+        return node.kind === 273 /* JSDocFunctionType */ &&
+            node.parameters.length > 0 &&
+            node.parameters[0].name &&
+            node.parameters[0].name.escapedText === "new";
+    }
+    ts.isJSDocConstructSignature = isJSDocConstructSignature;
+    function getAllJSDocs(node) {
+        if (ts.isJSDocTypedefTag(node)) {
+            return [node.parent];
+        }
+        return getJSDocCommentsAndTags(node);
+    }
+    ts.getAllJSDocs = getAllJSDocs;
+    function getSourceOfAssignment(node) {
+        return ts.isExpressionStatement(node) &&
+            node.expression && ts.isBinaryExpression(node.expression) &&
+            node.expression.operatorToken.kind === 58 /* EqualsToken */ &&
+            node.expression.right;
+    }
+    ts.getSourceOfAssignment = getSourceOfAssignment;
+    function getSingleInitializerOfVariableStatement(node, child) {
+        return ts.isVariableStatement(node) &&
+            node.declarationList.declarations.length > 0 &&
+            (!child || node.declarationList.declarations[0].initializer === child) &&
+            node.declarationList.declarations[0].initializer;
+    }
+    ts.getSingleInitializerOfVariableStatement = getSingleInitializerOfVariableStatement;
+    function getSingleVariableOfVariableStatement(node, child) {
+        return ts.isVariableStatement(node) &&
+            node.declarationList.declarations.length > 0 &&
+            (!child || node.declarationList.declarations[0] === child) &&
+            node.declarationList.declarations[0];
+    }
+    ts.getSingleVariableOfVariableStatement = getSingleVariableOfVariableStatement;
+    function getNestedModuleDeclaration(node) {
+        return node.kind === 233 /* ModuleDeclaration */ &&
+            node.body &&
+            node.body.kind === 233 /* ModuleDeclaration */ &&
+            node.body;
+    }
+    ts.getNestedModuleDeclaration = getNestedModuleDeclaration;
+    function getJSDocCommentsAndTags(node) {
+        var result;
+        getJSDocCommentsAndTagsWorker(node);
+        return result || ts.emptyArray;
+        function getJSDocCommentsAndTagsWorker(node) {
+            var parent = node.parent;
+            // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
+            // /**
+            //   * @param {number} name
+            //   * @returns {number}
+            //   */
+            // var x = function(name) { return name.length; }
+            if (parent && (parent.kind === 261 /* PropertyAssignment */ || getNestedModuleDeclaration(parent))) {
+                getJSDocCommentsAndTagsWorker(parent);
+            }
+            if (parent && parent.parent &&
+                (getSingleVariableOfVariableStatement(parent.parent, node) || getSourceOfAssignment(parent.parent))) {
+                getJSDocCommentsAndTagsWorker(parent.parent);
+            }
+            if (parent && parent.parent && parent.parent.parent && getSingleInitializerOfVariableStatement(parent.parent.parent, node)) {
+                getJSDocCommentsAndTagsWorker(parent.parent.parent);
+            }
+            // Pull parameter comments from declaring function as well
+            if (node.kind === 146 /* Parameter */) {
+                result = ts.addRange(result, ts.getJSDocParameterTags(node));
+            }
+            if (isVariableLike(node) && node.initializer && ts.hasJSDocNodes(node.initializer)) {
+                result = ts.addRange(result, node.initializer.jsDoc);
+            }
+            if (ts.hasJSDocNodes(node)) {
+                result = ts.addRange(result, node.jsDoc);
+            }
+        }
+    }
+    ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags;
+    /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
+    function getParameterSymbolFromJSDoc(node) {
+        if (node.symbol) {
+            return node.symbol;
+        }
+        if (!ts.isIdentifier(node.name)) {
+            return undefined;
+        }
+        var name = node.name.escapedText;
+        var host = getJSDocHost(node);
+        var decl = getSourceOfAssignment(host) ||
+            getSingleInitializerOfVariableStatement(host) ||
+            getSingleVariableOfVariableStatement(host) ||
+            getNestedModuleDeclaration(host) ||
+            host;
+        if (decl && ts.isFunctionLike(decl)) {
+            var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 71 /* Identifier */ && p.name.escapedText === name; });
+            return parameter && parameter.symbol;
+        }
+    }
+    ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc;
+    function getJSDocHost(node) {
+        ts.Debug.assert(node.parent.kind === 275 /* JSDocComment */);
+        return node.parent.parent;
+    }
+    ts.getJSDocHost = getJSDocHost;
+    function getTypeParameterFromJsDoc(node) {
+        var name = node.name.escapedText;
+        var typeParameters = node.parent.parent.parent.typeParameters;
+        return ts.find(typeParameters, function (p) { return p.name.escapedText === name; });
+    }
+    ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc;
+    function hasRestParameter(s) {
+        var last = ts.lastOrUndefined(s.parameters);
+        return last && isRestParameter(last);
+    }
+    ts.hasRestParameter = hasRestParameter;
+    function isRestParameter(node) {
+        return node.dotDotDotToken !== undefined;
+    }
+    ts.isRestParameter = isRestParameter;
+    var AssignmentKind;
+    (function (AssignmentKind) {
+        AssignmentKind[AssignmentKind["None"] = 0] = "None";
+        AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
+        AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
+    })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {}));
+    function getAssignmentTargetKind(node) {
+        var parent = node.parent;
+        while (true) {
+            switch (parent.kind) {
+                case 194 /* BinaryExpression */:
+                    var binaryOperator = parent.operatorToken.kind;
+                    return isAssignmentOperator(binaryOperator) && parent.left === node ?
+                        binaryOperator === 58 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ :
+                        0 /* None */;
+                case 192 /* PrefixUnaryExpression */:
+                case 193 /* PostfixUnaryExpression */:
+                    var unaryOperator = parent.operator;
+                    return unaryOperator === 43 /* PlusPlusToken */ || unaryOperator === 44 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */;
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                    return parent.initializer === node ? 1 /* Definite */ : 0 /* None */;
+                case 185 /* ParenthesizedExpression */:
+                case 177 /* ArrayLiteralExpression */:
+                case 198 /* SpreadElement */:
+                    node = parent;
+                    break;
+                case 262 /* ShorthandPropertyAssignment */:
+                    if (parent.name !== node) {
+                        return 0 /* None */;
+                    }
+                    node = parent.parent;
+                    break;
+                case 261 /* PropertyAssignment */:
+                    if (parent.name === node) {
+                        return 0 /* None */;
+                    }
+                    node = parent.parent;
+                    break;
+                default:
+                    return 0 /* None */;
+            }
+            parent = node.parent;
+        }
+    }
+    ts.getAssignmentTargetKind = getAssignmentTargetKind;
+    // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
+    // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
+    // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
+    // (Note that `p` is not a target in the above examples, only `a`.)
+    function isAssignmentTarget(node) {
+        return getAssignmentTargetKind(node) !== 0 /* None */;
+    }
+    ts.isAssignmentTarget = isAssignmentTarget;
+    // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
+    function isDeleteTarget(node) {
+        if (node.kind !== 179 /* PropertyAccessExpression */ && node.kind !== 180 /* ElementAccessExpression */) {
+            return false;
+        }
+        node = node.parent;
+        while (node && node.kind === 185 /* ParenthesizedExpression */) {
+            node = node.parent;
+        }
+        return node && node.kind === 188 /* DeleteExpression */;
+    }
+    ts.isDeleteTarget = isDeleteTarget;
+    function isNodeDescendantOf(node, ancestor) {
+        while (node) {
+            if (node === ancestor)
+                return true;
+            node = node.parent;
+        }
+        return false;
+    }
+    ts.isNodeDescendantOf = isNodeDescendantOf;
+    function isInAmbientContext(node) {
+        while (node) {
+            if (hasModifier(node, 2 /* Ambient */) || (node.kind === 265 /* SourceFile */ && node.isDeclarationFile)) {
+                return true;
+            }
+            node = node.parent;
+        }
+        return false;
+    }
+    ts.isInAmbientContext = isInAmbientContext;
+    // True if the given identifier, string literal, or number literal is the name of a declaration node
+    function isDeclarationName(name) {
+        switch (name.kind) {
+            case 71 /* Identifier */:
+            case 9 /* StringLiteral */:
+            case 8 /* NumericLiteral */:
+                return ts.isDeclaration(name.parent) && name.parent.name === name;
+            default:
+                return false;
+        }
+    }
+    ts.isDeclarationName = isDeclarationName;
+    /* @internal */
+    // See GH#16030
+    function isAnyDeclarationName(name) {
+        switch (name.kind) {
+            case 71 /* Identifier */:
+            case 9 /* StringLiteral */:
+            case 8 /* NumericLiteral */:
+                if (ts.isDeclaration(name.parent)) {
+                    return name.parent.name === name;
+                }
+                var binExp = name.parent.parent;
+                return ts.isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== 0 /* None */ && ts.getNameOfDeclaration(binExp) === name;
+            default:
+                return false;
+        }
+    }
+    ts.isAnyDeclarationName = isAnyDeclarationName;
+    function isLiteralComputedPropertyDeclarationName(node) {
+        return (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) &&
+            node.parent.kind === 144 /* ComputedPropertyName */ &&
+            ts.isDeclaration(node.parent.parent);
+    }
+    ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName;
+    // Return true if the given identifier is classified as an IdentifierName
+    function isIdentifierName(node) {
+        var parent = node.parent;
+        switch (parent.kind) {
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 264 /* EnumMember */:
+            case 261 /* PropertyAssignment */:
+            case 179 /* PropertyAccessExpression */:
+                // Name in member declaration or property name in property access
+                return parent.name === node;
+            case 143 /* QualifiedName */:
+                // Name on right hand side of dot in a type query
+                if (parent.right === node) {
+                    while (parent.kind === 143 /* QualifiedName */) {
+                        parent = parent.parent;
+                    }
+                    return parent.kind === 162 /* TypeQuery */;
+                }
+                return false;
+            case 176 /* BindingElement */:
+            case 242 /* ImportSpecifier */:
+                // Property name in binding element or import specifier
+                return parent.propertyName === node;
+            case 246 /* ExportSpecifier */:
+            case 253 /* JsxAttribute */:
+                // Any name in an export specifier or JSX Attribute
+                return true;
+        }
+        return false;
+    }
+    ts.isIdentifierName = isIdentifierName;
+    // An alias symbol is created by one of the following declarations:
+    // import <symbol> = ...
+    // import <symbol> from ...
+    // import * as <symbol> from ...
+    // import { x as <symbol> } from ...
+    // export { x as <symbol> } from ...
+    // export = <EntityNameExpression>
+    // export default <EntityNameExpression>
+    function isAliasSymbolDeclaration(node) {
+        return node.kind === 237 /* ImportEqualsDeclaration */ ||
+            node.kind === 236 /* NamespaceExportDeclaration */ ||
+            node.kind === 239 /* ImportClause */ && !!node.name ||
+            node.kind === 240 /* NamespaceImport */ ||
+            node.kind === 242 /* ImportSpecifier */ ||
+            node.kind === 246 /* ExportSpecifier */ ||
+            node.kind === 243 /* ExportAssignment */ && exportAssignmentIsAlias(node);
+    }
+    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
+    function exportAssignmentIsAlias(node) {
+        return isEntityNameExpression(node.expression);
+    }
+    ts.exportAssignmentIsAlias = exportAssignmentIsAlias;
+    function getClassExtendsHeritageClauseElement(node) {
+        var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */);
+        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
+    }
+    ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement;
+    function getClassImplementsHeritageClauseElements(node) {
+        var heritageClause = getHeritageClause(node.heritageClauses, 108 /* ImplementsKeyword */);
+        return heritageClause ? heritageClause.types : undefined;
+    }
+    ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
+    function getInterfaceBaseTypeNodes(node) {
+        var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */);
+        return heritageClause ? heritageClause.types : undefined;
+    }
+    ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
+    function getHeritageClause(clauses, kind) {
+        if (clauses) {
+            for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
+                var clause = clauses_1[_i];
+                if (clause.token === kind) {
+                    return clause;
+                }
+            }
+        }
+        return undefined;
+    }
+    ts.getHeritageClause = getHeritageClause;
+    function tryResolveScriptReference(host, sourceFile, reference) {
+        if (!host.getCompilerOptions().noResolve) {
+            var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName);
+            return host.getSourceFile(referenceFileName);
+        }
+    }
+    ts.tryResolveScriptReference = tryResolveScriptReference;
+    function getAncestor(node, kind) {
+        while (node) {
+            if (node.kind === kind) {
+                return node;
+            }
+            node = node.parent;
+        }
+        return undefined;
+    }
+    ts.getAncestor = getAncestor;
+    function getFileReferenceFromReferencePath(comment, commentRange) {
+        var simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
+        var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim");
+        if (simpleReferenceRegEx.test(comment)) {
+            if (isNoDefaultLibRegEx.test(comment)) {
+                return { isNoDefaultLib: true };
+            }
+            else {
+                var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
+                var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment);
+                var match = refMatchResult || refLibResult;
+                if (match) {
+                    var pos = commentRange.pos + match[1].length + match[2].length;
+                    return {
+                        fileReference: {
+                            pos: pos,
+                            end: pos + match[3].length,
+                            fileName: match[3]
+                        },
+                        isNoDefaultLib: false,
+                        isTypeReferenceDirective: !!refLibResult
+                    };
+                }
+                return {
+                    diagnosticMessage: ts.Diagnostics.Invalid_reference_directive_syntax,
+                    isNoDefaultLib: false
+                };
+            }
+        }
+        return undefined;
+    }
+    ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
+    function isKeyword(token) {
+        return 72 /* FirstKeyword */ <= token && token <= 142 /* LastKeyword */;
+    }
+    ts.isKeyword = isKeyword;
+    function isTrivia(token) {
+        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
+    }
+    ts.isTrivia = isTrivia;
+    var FunctionFlags;
+    (function (FunctionFlags) {
+        FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
+        FunctionFlags[FunctionFlags["Generator"] = 1] = "Generator";
+        FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
+        FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
+        FunctionFlags[FunctionFlags["AsyncGenerator"] = 3] = "AsyncGenerator";
+    })(FunctionFlags = ts.FunctionFlags || (ts.FunctionFlags = {}));
+    function getFunctionFlags(node) {
+        if (!node) {
+            return 4 /* Invalid */;
+        }
+        var flags = 0 /* Normal */;
+        switch (node.kind) {
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 151 /* MethodDeclaration */:
+                if (node.asteriskToken) {
+                    flags |= 1 /* Generator */;
+                }
+            // falls through
+            case 187 /* ArrowFunction */:
+                if (hasModifier(node, 256 /* Async */)) {
+                    flags |= 2 /* Async */;
+                }
+                break;
+        }
+        if (!node.body) {
+            flags |= 4 /* Invalid */;
+        }
+        return flags;
+    }
+    ts.getFunctionFlags = getFunctionFlags;
+    function isAsyncFunction(node) {
+        switch (node.kind) {
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+            case 151 /* MethodDeclaration */:
+                return node.body !== undefined
+                    && node.asteriskToken === undefined
+                    && hasModifier(node, 256 /* Async */);
+        }
+        return false;
+    }
+    ts.isAsyncFunction = isAsyncFunction;
+    function isStringOrNumericLiteral(node) {
+        var kind = node.kind;
+        return kind === 9 /* StringLiteral */
+            || kind === 8 /* NumericLiteral */;
+    }
+    ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
+    /**
+     * A declaration has a dynamic name if both of the following are true:
+     *   1. The declaration has a computed property name
+     *   2. The computed name is *not* expressed as Symbol.<name>, where name
+     *      is a property of the Symbol constructor that denotes a built in
+     *      Symbol.
+     */
+    function hasDynamicName(declaration) {
+        var name = ts.getNameOfDeclaration(declaration);
+        return name && isDynamicName(name);
+    }
+    ts.hasDynamicName = hasDynamicName;
+    function isDynamicName(name) {
+        return name.kind === 144 /* ComputedPropertyName */ &&
+            !isStringOrNumericLiteral(name.expression) &&
+            !isWellKnownSymbolSyntactically(name.expression);
+    }
+    ts.isDynamicName = isDynamicName;
+    /**
+     * Checks if the expression is of the form:
+     *    Symbol.name
+     * where Symbol is literally the word "Symbol", and name is any identifierName
+     */
+    function isWellKnownSymbolSyntactically(node) {
+        return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
+    }
+    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
+    function getPropertyNameForPropertyNameNode(name) {
+        if (name.kind === 71 /* Identifier */) {
+            return name.escapedText;
+        }
+        if (name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */) {
+            return escapeLeadingUnderscores(name.text);
+        }
+        if (name.kind === 144 /* ComputedPropertyName */) {
+            var nameExpression = name.expression;
+            if (isWellKnownSymbolSyntactically(nameExpression)) {
+                return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
+            }
+            else if (nameExpression.kind === 9 /* StringLiteral */ || nameExpression.kind === 8 /* NumericLiteral */) {
+                return escapeLeadingUnderscores(nameExpression.text);
+            }
+        }
+        return undefined;
+    }
+    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
+    function getTextOfIdentifierOrLiteral(node) {
+        if (node) {
+            if (node.kind === 71 /* Identifier */) {
+                return ts.idText(node);
+            }
+            if (node.kind === 9 /* StringLiteral */ ||
+                node.kind === 8 /* NumericLiteral */) {
+                return node.text;
+            }
+        }
+        return undefined;
+    }
+    ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral;
+    function getEscapedTextOfIdentifierOrLiteral(node) {
+        if (node) {
+            if (node.kind === 71 /* Identifier */) {
+                return node.escapedText;
+            }
+            if (node.kind === 9 /* StringLiteral */ ||
+                node.kind === 8 /* NumericLiteral */) {
+                return escapeLeadingUnderscores(node.text);
+            }
+        }
+        return undefined;
+    }
+    ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral;
+    function getPropertyNameForKnownSymbolName(symbolName) {
+        return "__@" + symbolName;
+    }
+    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
+    /**
+     * Includes the word "Symbol" with unicode escapes
+     */
+    function isESSymbolIdentifier(node) {
+        return node.kind === 71 /* Identifier */ && node.escapedText === "Symbol";
+    }
+    ts.isESSymbolIdentifier = isESSymbolIdentifier;
+    function isPushOrUnshiftIdentifier(node) {
+        return node.escapedText === "push" || node.escapedText === "unshift";
+    }
+    ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier;
+    function isParameterDeclaration(node) {
+        var root = getRootDeclaration(node);
+        return root.kind === 146 /* Parameter */;
+    }
+    ts.isParameterDeclaration = isParameterDeclaration;
+    function getRootDeclaration(node) {
+        while (node.kind === 176 /* BindingElement */) {
+            node = node.parent.parent;
+        }
+        return node;
+    }
+    ts.getRootDeclaration = getRootDeclaration;
+    function nodeStartsNewLexicalEnvironment(node) {
+        var kind = node.kind;
+        return kind === 152 /* Constructor */
+            || kind === 186 /* FunctionExpression */
+            || kind === 228 /* FunctionDeclaration */
+            || kind === 187 /* ArrowFunction */
+            || kind === 151 /* MethodDeclaration */
+            || kind === 153 /* GetAccessor */
+            || kind === 154 /* SetAccessor */
+            || kind === 233 /* ModuleDeclaration */
+            || kind === 265 /* SourceFile */;
+    }
+    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
+    }
+    ts.nodeIsSynthesized = nodeIsSynthesized;
+    function getOriginalSourceFile(sourceFile) {
+        return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile;
+    }
+    ts.getOriginalSourceFile = getOriginalSourceFile;
+    var Associativity;
+    (function (Associativity) {
+        Associativity[Associativity["Left"] = 0] = "Left";
+        Associativity[Associativity["Right"] = 1] = "Right";
+    })(Associativity = ts.Associativity || (ts.Associativity = {}));
+    function getExpressionAssociativity(expression) {
+        var operator = getOperator(expression);
+        var hasArguments = expression.kind === 182 /* NewExpression */ && expression.arguments !== undefined;
+        return getOperatorAssociativity(expression.kind, operator, hasArguments);
+    }
+    ts.getExpressionAssociativity = getExpressionAssociativity;
+    function getOperatorAssociativity(kind, operator, hasArguments) {
+        switch (kind) {
+            case 182 /* NewExpression */:
+                return hasArguments ? 0 /* Left */ : 1 /* Right */;
+            case 192 /* PrefixUnaryExpression */:
+            case 189 /* TypeOfExpression */:
+            case 190 /* VoidExpression */:
+            case 188 /* DeleteExpression */:
+            case 191 /* AwaitExpression */:
+            case 195 /* ConditionalExpression */:
+            case 197 /* YieldExpression */:
+                return 1 /* Right */;
+            case 194 /* BinaryExpression */:
+                switch (operator) {
+                    case 40 /* AsteriskAsteriskToken */:
+                    case 58 /* EqualsToken */:
+                    case 59 /* PlusEqualsToken */:
+                    case 60 /* MinusEqualsToken */:
+                    case 62 /* AsteriskAsteriskEqualsToken */:
+                    case 61 /* AsteriskEqualsToken */:
+                    case 63 /* SlashEqualsToken */:
+                    case 64 /* PercentEqualsToken */:
+                    case 65 /* LessThanLessThanEqualsToken */:
+                    case 66 /* GreaterThanGreaterThanEqualsToken */:
+                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                    case 68 /* AmpersandEqualsToken */:
+                    case 70 /* CaretEqualsToken */:
+                    case 69 /* BarEqualsToken */:
+                        return 1 /* Right */;
+                }
+        }
+        return 0 /* Left */;
+    }
+    ts.getOperatorAssociativity = getOperatorAssociativity;
+    function getExpressionPrecedence(expression) {
+        var operator = getOperator(expression);
+        var hasArguments = expression.kind === 182 /* NewExpression */ && expression.arguments !== undefined;
+        return getOperatorPrecedence(expression.kind, operator, hasArguments);
+    }
+    ts.getExpressionPrecedence = getExpressionPrecedence;
+    function getOperator(expression) {
+        if (expression.kind === 194 /* BinaryExpression */) {
+            return expression.operatorToken.kind;
+        }
+        else if (expression.kind === 192 /* PrefixUnaryExpression */ || expression.kind === 193 /* PostfixUnaryExpression */) {
+            return expression.operator;
+        }
+        else {
+            return expression.kind;
+        }
+    }
+    ts.getOperator = getOperator;
+    function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) {
+        switch (nodeKind) {
+            case 99 /* ThisKeyword */:
+            case 97 /* SuperKeyword */:
+            case 71 /* Identifier */:
+            case 95 /* NullKeyword */:
+            case 101 /* TrueKeyword */:
+            case 86 /* FalseKeyword */:
+            case 8 /* NumericLiteral */:
+            case 9 /* StringLiteral */:
+            case 177 /* ArrayLiteralExpression */:
+            case 178 /* ObjectLiteralExpression */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+            case 199 /* ClassExpression */:
+            case 249 /* JsxElement */:
+            case 250 /* JsxSelfClosingElement */:
+            case 12 /* RegularExpressionLiteral */:
+            case 13 /* NoSubstitutionTemplateLiteral */:
+            case 196 /* TemplateExpression */:
+            case 185 /* ParenthesizedExpression */:
+            case 200 /* OmittedExpression */:
+                return 19;
+            case 183 /* TaggedTemplateExpression */:
+            case 179 /* PropertyAccessExpression */:
+            case 180 /* ElementAccessExpression */:
+                return 18;
+            case 182 /* NewExpression */:
+                return hasArguments ? 18 : 17;
+            case 181 /* CallExpression */:
+                return 17;
+            case 193 /* PostfixUnaryExpression */:
+                return 16;
+            case 192 /* PrefixUnaryExpression */:
+            case 189 /* TypeOfExpression */:
+            case 190 /* VoidExpression */:
+            case 188 /* DeleteExpression */:
+            case 191 /* AwaitExpression */:
+                return 15;
+            case 194 /* BinaryExpression */:
+                switch (operatorKind) {
+                    case 51 /* ExclamationToken */:
+                    case 52 /* TildeToken */:
+                        return 15;
+                    case 40 /* AsteriskAsteriskToken */:
+                    case 39 /* AsteriskToken */:
+                    case 41 /* SlashToken */:
+                    case 42 /* PercentToken */:
+                        return 14;
+                    case 37 /* PlusToken */:
+                    case 38 /* MinusToken */:
+                        return 13;
+                    case 45 /* LessThanLessThanToken */:
+                    case 46 /* GreaterThanGreaterThanToken */:
+                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                        return 12;
+                    case 27 /* LessThanToken */:
+                    case 30 /* LessThanEqualsToken */:
+                    case 29 /* GreaterThanToken */:
+                    case 31 /* GreaterThanEqualsToken */:
+                    case 92 /* InKeyword */:
+                    case 93 /* InstanceOfKeyword */:
+                        return 11;
+                    case 32 /* EqualsEqualsToken */:
+                    case 34 /* EqualsEqualsEqualsToken */:
+                    case 33 /* ExclamationEqualsToken */:
+                    case 35 /* ExclamationEqualsEqualsToken */:
+                        return 10;
+                    case 48 /* AmpersandToken */:
+                        return 9;
+                    case 50 /* CaretToken */:
+                        return 8;
+                    case 49 /* BarToken */:
+                        return 7;
+                    case 53 /* AmpersandAmpersandToken */:
+                        return 6;
+                    case 54 /* BarBarToken */:
+                        return 5;
+                    case 58 /* EqualsToken */:
+                    case 59 /* PlusEqualsToken */:
+                    case 60 /* MinusEqualsToken */:
+                    case 62 /* AsteriskAsteriskEqualsToken */:
+                    case 61 /* AsteriskEqualsToken */:
+                    case 63 /* SlashEqualsToken */:
+                    case 64 /* PercentEqualsToken */:
+                    case 65 /* LessThanLessThanEqualsToken */:
+                    case 66 /* GreaterThanGreaterThanEqualsToken */:
+                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                    case 68 /* AmpersandEqualsToken */:
+                    case 70 /* CaretEqualsToken */:
+                    case 69 /* BarEqualsToken */:
+                        return 3;
+                    case 26 /* CommaToken */:
+                        return 0;
+                    default:
+                        return -1;
+                }
+            case 195 /* ConditionalExpression */:
+                return 4;
+            case 197 /* YieldExpression */:
+                return 2;
+            case 198 /* SpreadElement */:
+                return 1;
+            case 289 /* CommaListExpression */:
+                return 0;
+            default:
+                return -1;
+        }
+    }
+    ts.getOperatorPrecedence = getOperatorPrecedence;
+    function createDiagnosticCollection() {
+        var nonFileDiagnostics = [];
+        var fileDiagnostics = ts.createMap();
+        var diagnosticsModified = false;
+        var modificationCount = 0;
+        return {
+            add: add,
+            getGlobalDiagnostics: getGlobalDiagnostics,
+            getDiagnostics: getDiagnostics,
+            getModificationCount: getModificationCount,
+            reattachFileDiagnostics: reattachFileDiagnostics
+        };
+        function getModificationCount() {
+            return modificationCount;
+        }
+        function reattachFileDiagnostics(newFile) {
+            ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; });
+        }
+        function add(diagnostic) {
+            var diagnostics;
+            if (diagnostic.file) {
+                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
+                if (!diagnostics) {
+                    diagnostics = [];
+                    fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
+                }
+            }
+            else {
+                diagnostics = nonFileDiagnostics;
+            }
+            diagnostics.push(diagnostic);
+            diagnosticsModified = true;
+            modificationCount++;
+        }
+        function getGlobalDiagnostics() {
+            sortAndDeduplicate();
+            return nonFileDiagnostics;
+        }
+        function getDiagnostics(fileName) {
+            sortAndDeduplicate();
+            if (fileName) {
+                return fileDiagnostics.get(fileName) || [];
+            }
+            var allDiagnostics = [];
+            function pushDiagnostic(d) {
+                allDiagnostics.push(d);
+            }
+            ts.forEach(nonFileDiagnostics, pushDiagnostic);
+            fileDiagnostics.forEach(function (diagnostics) {
+                ts.forEach(diagnostics, pushDiagnostic);
+            });
+            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
+        }
+        function sortAndDeduplicate() {
+            if (!diagnosticsModified) {
+                return;
+            }
+            diagnosticsModified = false;
+            nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics);
+            fileDiagnostics.forEach(function (diagnostics, key) {
+                fileDiagnostics.set(key, ts.sortAndDeduplicateDiagnostics(diagnostics));
+            });
+        }
+    }
+    ts.createDiagnosticCollection = createDiagnosticCollection;
+    // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
+    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
+    // the language service. These characters should be escaped when printing, and if any characters are added,
+    // the map below must be updated. Note that this regexp *does not* include the 'delete' character.
+    // There is no reason for this other than that JSON.stringify does not handle it either.
+    var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
+    var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
+    var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
+    var escapedCharsMap = ts.createMapFromTemplate({
+        "\0": "\\0",
+        "\t": "\\t",
+        "\v": "\\v",
+        "\f": "\\f",
+        "\b": "\\b",
+        "\r": "\\r",
+        "\n": "\\n",
+        "\\": "\\\\",
+        "\"": "\\\"",
+        "\'": "\\\'",
+        "\`": "\\\`",
+        "\u2028": "\\u2028",
+        "\u2029": "\\u2029",
+        "\u0085": "\\u0085" // nextLine
+    });
+    var escapedNullRegExp = /\\0[0-9]/g;
+    /**
+     * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
+     * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
+     * Note that this doesn't actually wrap the input in double quotes.
+     */
+    function escapeString(s, quoteChar) {
+        var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp :
+            quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp :
+                doubleQuoteEscapedCharsRegExp;
+        return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement);
+    }
+    ts.escapeString = escapeString;
+    function nullReplacement(c) {
+        return "\\x00" + c.charAt(c.length - 1);
+    }
+    function getReplacement(c) {
+        return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
+    }
+    function isIntrinsicJsxName(name) {
+        // An escaped identifier had a leading underscore prior to being escaped, which would return true
+        // The escape adds an extra underscore which does not change the result
+        var ch = name.substr(0, 1);
+        return ch.toLowerCase() === ch;
+    }
+    ts.isIntrinsicJsxName = isIntrinsicJsxName;
+    function get16BitUnicodeEscapeSequence(charCode) {
+        var hexCharCode = charCode.toString(16).toUpperCase();
+        var paddedHexCode = ("0000" + hexCharCode).slice(-4);
+        return "\\u" + paddedHexCode;
+    }
+    var nonAsciiCharacters = /[^\u0000-\u007F]/g;
+    function escapeNonAsciiString(s, quoteChar) {
+        s = escapeString(s, quoteChar);
+        // Replace non-ASCII characters with '\uNNNN' escapes if any exist.
+        // Otherwise just return the original string.
+        return nonAsciiCharacters.test(s) ?
+            s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) :
+            s;
+    }
+    ts.escapeNonAsciiString = escapeNonAsciiString;
+    var indentStrings = ["", "    "];
+    function getIndentString(level) {
+        if (indentStrings[level] === undefined) {
+            indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
+        }
+        return indentStrings[level];
+    }
+    ts.getIndentString = getIndentString;
+    function getIndentSize() {
+        return indentStrings[1].length;
+    }
+    ts.getIndentSize = getIndentSize;
+    function createTextWriter(newLine) {
+        var output;
+        var indent;
+        var lineStart;
+        var lineCount;
+        var linePos;
+        function write(s) {
+            if (s && s.length) {
+                if (lineStart) {
+                    output += getIndentString(indent);
+                    lineStart = false;
+                }
+                output += s;
+            }
+        }
+        function reset() {
+            output = "";
+            indent = 0;
+            lineStart = true;
+            lineCount = 0;
+            linePos = 0;
+        }
+        function rawWrite(s) {
+            if (s !== undefined) {
+                if (lineStart) {
+                    lineStart = false;
+                }
+                output += s;
+            }
+        }
+        function writeLiteral(s) {
+            if (s && s.length) {
+                write(s);
+                var lineStartsOfS = ts.computeLineStarts(s);
+                if (lineStartsOfS.length > 1) {
+                    lineCount = lineCount + lineStartsOfS.length - 1;
+                    linePos = output.length - s.length + ts.lastOrUndefined(lineStartsOfS);
+                }
+            }
+        }
+        function writeLine() {
+            if (!lineStart) {
+                output += newLine;
+                lineCount++;
+                linePos = output.length;
+                lineStart = true;
+            }
+        }
+        function writeTextOfNode(text, node) {
+            write(getTextOfNodeFromSourceText(text, node));
+        }
+        reset();
+        return {
+            write: write,
+            rawWrite: rawWrite,
+            writeTextOfNode: writeTextOfNode,
+            writeLiteral: writeLiteral,
+            writeLine: writeLine,
+            increaseIndent: function () { indent++; },
+            decreaseIndent: function () { indent--; },
+            getIndent: function () { return indent; },
+            getTextPos: function () { return output.length; },
+            getLine: function () { return lineCount + 1; },
+            getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
+            getText: function () { return output; },
+            isAtStartOfLine: function () { return lineStart; },
+            reset: reset
+        };
+    }
+    ts.createTextWriter = createTextWriter;
+    function getResolvedExternalModuleName(host, file) {
+        return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
+    }
+    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
+    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
+        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
+        if (!file || file.isDeclarationFile) {
+            return undefined;
+        }
+        return getResolvedExternalModuleName(host, file);
+    }
+    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
+    /**
+     * Resolves a local path to a path which is absolute to the base of the emit
+     */
+    function getExternalModuleNameFromPath(host, fileName) {
+        var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); };
+        var dir = ts.toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
+        var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
+        var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
+        return ts.removeFileExtension(relativePath);
+    }
+    ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
+    function getOwnEmitOutputFilePath(sourceFile, host, extension) {
+        var compilerOptions = host.getCompilerOptions();
+        var emitOutputFilePathWithoutExtension;
+        if (compilerOptions.outDir) {
+            emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
+        }
+        else {
+            emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
+        }
+        return emitOutputFilePathWithoutExtension + extension;
+    }
+    ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
+    function getDeclarationEmitOutputFilePath(sourceFile, host) {
+        var options = host.getCompilerOptions();
+        var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
+        var path = outputDir
+            ? getSourceFilePathInNewDir(sourceFile, host, outputDir)
+            : sourceFile.fileName;
+        return ts.removeFileExtension(path) + ".d.ts" /* Dts */;
+    }
+    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
+    /**
+     * Gets the source files that are expected to have an emit output.
+     *
+     * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
+     * transformations.
+     *
+     * @param host An EmitHost.
+     * @param targetSourceFile An optional target source file to emit.
+     */
+    function getSourceFilesToEmit(host, targetSourceFile) {
+        var options = host.getCompilerOptions();
+        var isSourceFileFromExternalLibrary = function (file) { return host.isSourceFileFromExternalLibrary(file); };
+        if (options.outFile || options.out) {
+            var moduleKind = ts.getEmitModuleKind(options);
+            var moduleEmitEnabled_1 = moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System;
+            // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
+            return ts.filter(host.getSourceFiles(), function (sourceFile) {
+                return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary);
+            });
+        }
+        else {
+            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
+            return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary); });
+        }
+    }
+    ts.getSourceFilesToEmit = getSourceFilesToEmit;
+    /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
+    function sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary) {
+        return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile);
+    }
+    ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted;
+    function getSourceFilePathInNewDir(sourceFile, host, newDirPath) {
+        var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
+        var commonSourceDirectory = host.getCommonSourceDirectory();
+        var isSourceFileInCommonSourceDirectory = host.getCanonicalFileName(sourceFilePath).indexOf(host.getCanonicalFileName(commonSourceDirectory)) === 0;
+        sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
+        return ts.combinePaths(newDirPath, sourceFilePath);
+    }
+    ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
+    function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) {
+        host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
+            diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
+        }, sourceFiles);
+    }
+    ts.writeFile = writeFile;
+    function getLineOfLocalPosition(currentSourceFile, pos) {
+        return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
+    }
+    ts.getLineOfLocalPosition = getLineOfLocalPosition;
+    function getLineOfLocalPositionFromLineMap(lineMap, pos) {
+        return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
+    }
+    ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
+    function getFirstConstructorWithBody(node) {
+        return ts.forEach(node.members, function (member) {
+            if (member.kind === 152 /* Constructor */ && nodeIsPresent(member.body)) {
+                return member;
+            }
+        });
+    }
+    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
+    function getSetAccessorValueParameter(accessor) {
+        if (accessor && accessor.parameters.length > 0) {
+            var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
+            return accessor.parameters[hasThis ? 1 : 0];
+        }
+    }
+    /** Get the type annotation for the value parameter. */
+    function getSetAccessorTypeAnnotationNode(accessor) {
+        var parameter = getSetAccessorValueParameter(accessor);
+        return parameter && parameter.type;
+    }
+    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
+    function getThisParameter(signature) {
+        if (signature.parameters.length) {
+            var thisParameter = signature.parameters[0];
+            if (parameterIsThisKeyword(thisParameter)) {
+                return thisParameter;
+            }
+        }
+    }
+    ts.getThisParameter = getThisParameter;
+    function parameterIsThisKeyword(parameter) {
+        return isThisIdentifier(parameter.name);
+    }
+    ts.parameterIsThisKeyword = parameterIsThisKeyword;
+    function isThisIdentifier(node) {
+        return node && node.kind === 71 /* Identifier */ && identifierIsThisKeyword(node);
+    }
+    ts.isThisIdentifier = isThisIdentifier;
+    function identifierIsThisKeyword(id) {
+        return id.originalKeywordKind === 99 /* ThisKeyword */;
+    }
+    ts.identifierIsThisKeyword = identifierIsThisKeyword;
+    function getAllAccessorDeclarations(declarations, accessor) {
+        var firstAccessor;
+        var secondAccessor;
+        var getAccessor;
+        var setAccessor;
+        if (hasDynamicName(accessor)) {
+            firstAccessor = accessor;
+            if (accessor.kind === 153 /* GetAccessor */) {
+                getAccessor = accessor;
+            }
+            else if (accessor.kind === 154 /* SetAccessor */) {
+                setAccessor = accessor;
+            }
+            else {
+                ts.Debug.fail("Accessor has wrong kind");
+            }
+        }
+        else {
+            ts.forEach(declarations, function (member) {
+                if ((member.kind === 153 /* GetAccessor */ || member.kind === 154 /* SetAccessor */)
+                    && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) {
+                    var memberName = getPropertyNameForPropertyNameNode(member.name);
+                    var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
+                    if (memberName === accessorName) {
+                        if (!firstAccessor) {
+                            firstAccessor = member;
+                        }
+                        else if (!secondAccessor) {
+                            secondAccessor = member;
+                        }
+                        if (member.kind === 153 /* GetAccessor */ && !getAccessor) {
+                            getAccessor = member;
+                        }
+                        if (member.kind === 154 /* SetAccessor */ && !setAccessor) {
+                            setAccessor = member;
+                        }
+                    }
+                }
+            });
+        }
+        return {
+            firstAccessor: firstAccessor,
+            secondAccessor: secondAccessor,
+            getAccessor: getAccessor,
+            setAccessor: setAccessor
+        };
+    }
+    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
+    /**
+     * Gets the effective type annotation of a variable, parameter, or property. If the node was
+     * parsed in a JavaScript file, gets the type annotation from JSDoc.
+     */
+    function getEffectiveTypeAnnotationNode(node, checkJSDoc) {
+        if (node.type) {
+            return node.type;
+        }
+        if (checkJSDoc || isInJavaScriptFile(node)) {
+            return ts.getJSDocType(node);
+        }
+    }
+    ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode;
+    /**
+     * Gets the effective return type annotation of a signature. If the node was parsed in a
+     * JavaScript file, gets the return type annotation from JSDoc.
+     */
+    function getEffectiveReturnTypeNode(node, checkJSDoc) {
+        if (node.type) {
+            return node.type;
+        }
+        if (checkJSDoc || isInJavaScriptFile(node)) {
+            return ts.getJSDocReturnType(node);
+        }
+    }
+    ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode;
+    /**
+     * Gets the effective type parameters. If the node was parsed in a
+     * JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
+     */
+    function getEffectiveTypeParameterDeclarations(node, checkJSDoc) {
+        if (node.typeParameters) {
+            return node.typeParameters;
+        }
+        if (checkJSDoc || isInJavaScriptFile(node)) {
+            var templateTag = ts.getJSDocTemplateTag(node);
+            return templateTag && templateTag.typeParameters;
+        }
+    }
+    ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations;
+    /**
+     * Gets the effective type annotation of the value parameter of a set accessor. If the node
+     * was parsed in a JavaScript file, gets the type annotation from JSDoc.
+     */
+    function getEffectiveSetAccessorTypeAnnotationNode(node, checkJSDoc) {
+        var parameter = getSetAccessorValueParameter(node);
+        return parameter && getEffectiveTypeAnnotationNode(parameter, checkJSDoc);
+    }
+    ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode;
+    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
+        emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
+    }
+    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
+    function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) {
+        // If the leading comments start on different line than the start of node, write new line
+        if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
+            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
+            writer.writeLine();
+        }
+    }
+    ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition;
+    function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) {
+        // If the leading comments start on different line than the start of node, write new line
+        if (pos !== commentPos &&
+            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
+            writer.writeLine();
+        }
+    }
+    ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition;
+    function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) {
+        if (comments && comments.length > 0) {
+            if (leadingSeparator) {
+                writer.write(" ");
+            }
+            var emitInterveningSeparator = false;
+            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
+                var comment = comments_1[_i];
+                if (emitInterveningSeparator) {
+                    writer.write(" ");
+                    emitInterveningSeparator = false;
+                }
+                writeComment(text, lineMap, writer, comment.pos, comment.end, newLine);
+                if (comment.hasTrailingNewLine) {
+                    writer.writeLine();
+                }
+                else {
+                    emitInterveningSeparator = true;
+                }
+            }
+            if (emitInterveningSeparator && trailingSeparator) {
+                writer.write(" ");
+            }
+        }
+    }
+    ts.emitComments = emitComments;
+    /**
+     * Detached comment is a comment at the top of file or function body that is separated from
+     * the next statement by space.
+     */
+    function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
+        var leadingComments;
+        var currentDetachedCommentInfo;
+        if (removeComments) {
+            // removeComments is true, only reserve pinned comment at the top of file
+            // For example:
+            //      /*! Pinned Comment */
+            //
+            //      var x = 10;
+            if (node.pos === 0) {
+                leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal);
+            }
+        }
+        else {
+            // removeComments is false, just get detached as normal and bypass the process to filter comment
+            leadingComments = ts.getLeadingCommentRanges(text, node.pos);
+        }
+        if (leadingComments) {
+            var detachedComments = [];
+            var lastComment = void 0;
+            for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
+                var comment = leadingComments_1[_i];
+                if (lastComment) {
+                    var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
+                    var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
+                    if (commentLine >= lastCommentLine + 2) {
+                        // There was a blank line between the last comment and this comment.  This
+                        // comment is not part of the copyright comments.  Return what we have so
+                        // far.
+                        break;
+                    }
+                }
+                detachedComments.push(comment);
+                lastComment = comment;
+            }
+            if (detachedComments.length) {
+                // All comments look like they could have been part of the copyright header.  Make
+                // sure there is at least one blank line between it and the node.  If not, it's not
+                // a copyright header.
+                var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
+                var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
+                if (nodeLine >= lastCommentLine + 2) {
+                    // Valid detachedComments
+                    emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
+                    emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
+                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
+                }
+            }
+        }
+        return currentDetachedCommentInfo;
+        function isPinnedCommentLocal(comment) {
+            return isPinnedComment(text, comment);
+        }
+    }
+    ts.emitDetachedComments = emitDetachedComments;
+    function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) {
+        if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) {
+            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos);
+            var lineCount = lineMap.length;
+            var firstCommentLineIndent = void 0;
+            for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
+                var nextLineStart = (currentLine + 1) === lineCount
+                    ? text.length + 1
+                    : lineMap[currentLine + 1];
+                if (pos !== commentPos) {
+                    // If we are not emitting first line, we need to write the spaces to adjust the alignment
+                    if (firstCommentLineIndent === undefined) {
+                        firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos);
+                    }
+                    // These are number of spaces writer is going to write at current indent
+                    var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
+                    // Number of spaces we want to be writing
+                    // eg: Assume writer indent
+                    // module m {
+                    //         /* starts at character 9 this is line 1
+                    //    * starts at character pos 4 line                        --1  = 8 - 8 + 3
+                    //   More left indented comment */                            --2  = 8 - 8 + 2
+                    //     class c { }
+                    // }
+                    // module m {
+                    //     /* this is line 1 -- Assume current writer indent 8
+                    //      * line                                                --3 = 8 - 4 + 5
+                    //            More right indented comment */                  --4 = 8 - 4 + 11
+                    //     class c { }
+                    // }
+                    var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
+                    if (spacesToEmit > 0) {
+                        var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
+                        var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
+                        // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
+                        writer.rawWrite(indentSizeSpaceString);
+                        // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces)
+                        while (numberOfSingleSpacesToEmit) {
+                            writer.rawWrite(" ");
+                            numberOfSingleSpacesToEmit--;
+                        }
+                    }
+                    else {
+                        // No spaces to emit write empty string
+                        writer.rawWrite("");
+                    }
+                }
+                // Write the comment line text
+                writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart);
+                pos = nextLineStart;
+            }
+        }
+        else {
+            // Single line comment of style //....
+            writer.write(text.substring(commentPos, commentEnd));
+        }
+    }
+    ts.writeCommentRange = writeCommentRange;
+    function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) {
+        var end = Math.min(commentEnd, nextLineStart - 1);
+        var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
+        if (currentLineText) {
+            // trimmed forward and ending spaces text
+            writer.write(currentLineText);
+            if (end !== commentEnd) {
+                writer.writeLine();
+            }
+        }
+        else {
+            // Empty string - make sure we write empty line
+            writer.writeLiteral(newLine);
+        }
+    }
+    function calculateIndent(text, pos, end) {
+        var currentLineIndent = 0;
+        for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) {
+            if (text.charCodeAt(pos) === 9 /* tab */) {
+                // Tabs = TabSize = indent size and go to next tabStop
+                currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
+            }
+            else {
+                // Single space
+                currentLineIndent++;
+            }
+        }
+        return currentLineIndent;
+    }
+    function hasModifiers(node) {
+        return getModifierFlags(node) !== 0 /* None */;
+    }
+    ts.hasModifiers = hasModifiers;
+    function hasModifier(node, flags) {
+        return !!getSelectedModifierFlags(node, flags);
+    }
+    ts.hasModifier = hasModifier;
+    function getSelectedModifierFlags(node, flags) {
+        return getModifierFlags(node) & flags;
+    }
+    ts.getSelectedModifierFlags = getSelectedModifierFlags;
+    function getModifierFlags(node) {
+        if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) {
+            return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */;
+        }
+        var flags = getModifierFlagsNoCache(node);
+        node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */;
+        return flags;
+    }
+    ts.getModifierFlags = getModifierFlags;
+    /* @internal */
+    function getModifierFlagsNoCache(node) {
+        var flags = 0 /* None */;
+        if (node.modifiers) {
+            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
+                var modifier = _a[_i];
+                flags |= modifierToFlag(modifier.kind);
+            }
+        }
+        if (node.flags & 4 /* NestedNamespace */ || (node.kind === 71 /* Identifier */ && node.isInJSDocNamespace)) {
+            flags |= 1 /* Export */;
+        }
+        return flags;
+    }
+    ts.getModifierFlagsNoCache = getModifierFlagsNoCache;
+    function modifierToFlag(token) {
+        switch (token) {
+            case 115 /* StaticKeyword */: return 32 /* Static */;
+            case 114 /* PublicKeyword */: return 4 /* Public */;
+            case 113 /* ProtectedKeyword */: return 16 /* Protected */;
+            case 112 /* PrivateKeyword */: return 8 /* Private */;
+            case 117 /* AbstractKeyword */: return 128 /* Abstract */;
+            case 84 /* ExportKeyword */: return 1 /* Export */;
+            case 124 /* DeclareKeyword */: return 2 /* Ambient */;
+            case 76 /* ConstKeyword */: return 2048 /* Const */;
+            case 79 /* DefaultKeyword */: return 512 /* Default */;
+            case 120 /* AsyncKeyword */: return 256 /* Async */;
+            case 131 /* ReadonlyKeyword */: return 64 /* Readonly */;
+        }
+        return 0 /* None */;
+    }
+    ts.modifierToFlag = modifierToFlag;
+    function isLogicalOperator(token) {
+        return token === 54 /* BarBarToken */
+            || token === 53 /* AmpersandAmpersandToken */
+            || token === 51 /* ExclamationToken */;
+    }
+    ts.isLogicalOperator = isLogicalOperator;
+    function isAssignmentOperator(token) {
+        return token >= 58 /* FirstAssignment */ && token <= 70 /* LastAssignment */;
+    }
+    ts.isAssignmentOperator = isAssignmentOperator;
+    /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
+    function tryGetClassExtendingExpressionWithTypeArguments(node) {
+        if (node.kind === 201 /* ExpressionWithTypeArguments */ &&
+            node.parent.token === 85 /* ExtendsKeyword */ &&
+            ts.isClassLike(node.parent.parent)) {
+            return node.parent.parent;
+        }
+    }
+    ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments;
+    function isAssignmentExpression(node, excludeCompoundAssignment) {
+        return ts.isBinaryExpression(node)
+            && (excludeCompoundAssignment
+                ? node.operatorToken.kind === 58 /* EqualsToken */
+                : isAssignmentOperator(node.operatorToken.kind))
+            && ts.isLeftHandSideExpression(node.left);
+    }
+    ts.isAssignmentExpression = isAssignmentExpression;
+    function isDestructuringAssignment(node) {
+        if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
+            var kind = node.left.kind;
+            return kind === 178 /* ObjectLiteralExpression */
+                || kind === 177 /* ArrayLiteralExpression */;
+        }
+        return false;
+    }
+    ts.isDestructuringAssignment = isDestructuringAssignment;
+    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
+        return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
+    }
+    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
+    function isExpressionWithTypeArgumentsInClassImplementsClause(node) {
+        return node.kind === 201 /* ExpressionWithTypeArguments */
+            && isEntityNameExpression(node.expression)
+            && node.parent
+            && node.parent.token === 108 /* ImplementsKeyword */
+            && node.parent.parent
+            && ts.isClassLike(node.parent.parent);
+    }
+    ts.isExpressionWithTypeArgumentsInClassImplementsClause = isExpressionWithTypeArgumentsInClassImplementsClause;
+    function isEntityNameExpression(node) {
+        return node.kind === 71 /* Identifier */ ||
+            node.kind === 179 /* PropertyAccessExpression */ && isEntityNameExpression(node.expression);
+    }
+    ts.isEntityNameExpression = isEntityNameExpression;
+    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
+        return (node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node) ||
+            (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node);
+    }
+    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
+    function isEmptyObjectLiteral(expression) {
+        return expression.kind === 178 /* ObjectLiteralExpression */ &&
+            expression.properties.length === 0;
+    }
+    ts.isEmptyObjectLiteral = isEmptyObjectLiteral;
+    function isEmptyArrayLiteral(expression) {
+        return expression.kind === 177 /* ArrayLiteralExpression */ &&
+            expression.elements.length === 0;
+    }
+    ts.isEmptyArrayLiteral = isEmptyArrayLiteral;
+    function getLocalSymbolForExportDefault(symbol) {
+        return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
+    }
+    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
+    function isExportDefaultSymbol(symbol) {
+        return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */);
+    }
+    /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
+    function tryExtractTypeScriptExtension(fileName) {
+        return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); });
+    }
+    ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension;
+    /**
+     * Replace each instance of non-ascii characters by one, two, three, or four escape sequences
+     * representing the UTF-8 encoding of the character, and return the expanded char code list.
+     */
+    function getExpandedCharCodes(input) {
+        var output = [];
+        var length = input.length;
+        for (var i = 0; i < length; i++) {
+            var charCode = input.charCodeAt(i);
+            // handel utf8
+            if (charCode < 0x80) {
+                output.push(charCode);
+            }
+            else if (charCode < 0x800) {
+                output.push((charCode >> 6) | 192);
+                output.push((charCode & 63) | 128);
+            }
+            else if (charCode < 0x10000) {
+                output.push((charCode >> 12) | 224);
+                output.push(((charCode >> 6) & 63) | 128);
+                output.push((charCode & 63) | 128);
+            }
+            else if (charCode < 0x20000) {
+                output.push((charCode >> 18) | 240);
+                output.push(((charCode >> 12) & 63) | 128);
+                output.push(((charCode >> 6) & 63) | 128);
+                output.push((charCode & 63) | 128);
+            }
+            else {
+                ts.Debug.assert(false, "Unexpected code point");
+            }
+        }
+        return output;
+    }
+    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+    /**
+     * Converts a string to a base-64 encoded ASCII string.
+     */
+    function convertToBase64(input) {
+        var result = "";
+        var charCodes = getExpandedCharCodes(input);
+        var i = 0;
+        var length = charCodes.length;
+        var byte1, byte2, byte3, byte4;
+        while (i < length) {
+            // Convert every 6-bits in the input 3 character points
+            // into a base64 digit
+            byte1 = charCodes[i] >> 2;
+            byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
+            byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
+            byte4 = charCodes[i + 2] & 63;
+            // We are out of characters in the input, set the extra
+            // digits to 64 (padding character).
+            if (i + 1 >= length) {
+                byte3 = byte4 = 64;
+            }
+            else if (i + 2 >= length) {
+                byte4 = 64;
+            }
+            // Write to the output
+            result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
+            i += 3;
+        }
+        return result;
+    }
+    ts.convertToBase64 = convertToBase64;
+    var carriageReturnLineFeed = "\r\n";
+    var lineFeed = "\n";
+    function getNewLineCharacter(options, system) {
+        switch (options.newLine) {
+            case 0 /* CarriageReturnLineFeed */:
+                return carriageReturnLineFeed;
+            case 1 /* LineFeed */:
+                return lineFeed;
+        }
+        return system ? system.newLine : ts.sys ? ts.sys.newLine : carriageReturnLineFeed;
+    }
+    ts.getNewLineCharacter = getNewLineCharacter;
+    /**
+     * Formats an enum value as a string for debugging and debug assertions.
+     */
+    function formatEnum(value, enumObject, isFlags) {
+        if (value === void 0) { value = 0; }
+        var members = getEnumMembers(enumObject);
+        if (value === 0) {
+            return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
+        }
+        if (isFlags) {
+            var result = "";
+            var remainingFlags = value;
+            for (var i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
+                var _a = members[i], enumValue = _a[0], enumName = _a[1];
+                if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
+                    remainingFlags &= ~enumValue;
+                    result = "" + enumName + (result ? ", " : "") + result;
+                }
+            }
+            if (remainingFlags === 0) {
+                return result;
+            }
+        }
+        else {
+            for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
+                var _b = members_1[_i], enumValue = _b[0], enumName = _b[1];
+                if (enumValue === value) {
+                    return enumName;
+                }
+            }
+        }
+        return value.toString();
+    }
+    function getEnumMembers(enumObject) {
+        var result = [];
+        for (var name in enumObject) {
+            var value = enumObject[name];
+            if (typeof value === "number") {
+                result.push([value, name]);
+            }
+        }
+        return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); });
+    }
+    function formatSyntaxKind(kind) {
+        return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false);
+    }
+    ts.formatSyntaxKind = formatSyntaxKind;
+    function formatModifierFlags(flags) {
+        return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true);
+    }
+    ts.formatModifierFlags = formatModifierFlags;
+    function formatTransformFlags(flags) {
+        return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true);
+    }
+    ts.formatTransformFlags = formatTransformFlags;
+    function formatEmitFlags(flags) {
+        return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true);
+    }
+    ts.formatEmitFlags = formatEmitFlags;
+    function formatSymbolFlags(flags) {
+        return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true);
+    }
+    ts.formatSymbolFlags = formatSymbolFlags;
+    function formatTypeFlags(flags) {
+        return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true);
+    }
+    ts.formatTypeFlags = formatTypeFlags;
+    function formatObjectFlags(flags) {
+        return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true);
+    }
+    ts.formatObjectFlags = formatObjectFlags;
+    /**
+     * Creates a new TextRange from the provided pos and end.
+     *
+     * @param pos The start position.
+     * @param end The end position.
+     */
+    function createRange(pos, end) {
+        return { pos: pos, end: end };
+    }
+    ts.createRange = createRange;
+    /**
+     * Creates a new TextRange from a provided range with a new end position.
+     *
+     * @param range A TextRange.
+     * @param end The new end position.
+     */
+    function moveRangeEnd(range, end) {
+        return createRange(range.pos, end);
+    }
+    ts.moveRangeEnd = moveRangeEnd;
+    /**
+     * Creates a new TextRange from a provided range with a new start position.
+     *
+     * @param range A TextRange.
+     * @param pos The new Start position.
+     */
+    function moveRangePos(range, pos) {
+        return createRange(pos, range.end);
+    }
+    ts.moveRangePos = moveRangePos;
+    /**
+     * Moves the start position of a range past any decorators.
+     */
+    function moveRangePastDecorators(node) {
+        return node.decorators && node.decorators.length > 0
+            ? moveRangePos(node, node.decorators.end)
+            : node;
+    }
+    ts.moveRangePastDecorators = moveRangePastDecorators;
+    /**
+     * Moves the start position of a range past any decorators or modifiers.
+     */
+    function moveRangePastModifiers(node) {
+        return node.modifiers && node.modifiers.length > 0
+            ? moveRangePos(node, node.modifiers.end)
+            : moveRangePastDecorators(node);
+    }
+    ts.moveRangePastModifiers = moveRangePastModifiers;
+    /**
+     * Determines whether a TextRange has the same start and end positions.
+     *
+     * @param range A TextRange.
+     */
+    function isCollapsedRange(range) {
+        return range.pos === range.end;
+    }
+    ts.isCollapsedRange = isCollapsedRange;
+    /**
+     * Creates a new TextRange for a token at the provides start position.
+     *
+     * @param pos The start position.
+     * @param token The token.
+     */
+    function createTokenRange(pos, token) {
+        return createRange(pos, pos + ts.tokenToString(token).length);
+    }
+    ts.createTokenRange = createTokenRange;
+    function rangeIsOnSingleLine(range, sourceFile) {
+        return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
+    }
+    ts.rangeIsOnSingleLine = rangeIsOnSingleLine;
+    function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
+        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), getStartPositionOfRange(range2, sourceFile), sourceFile);
+    }
+    ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine;
+    function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
+        return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
+    }
+    ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine;
+    function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
+        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), range2.end, sourceFile);
+    }
+    ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd;
+    function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
+        return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile), sourceFile);
+    }
+    ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart;
+    function positionsAreOnSameLine(pos1, pos2, sourceFile) {
+        return pos1 === pos2 ||
+            getLineOfLocalPosition(sourceFile, pos1) === getLineOfLocalPosition(sourceFile, pos2);
+    }
+    ts.positionsAreOnSameLine = positionsAreOnSameLine;
+    function getStartPositionOfRange(range, sourceFile) {
+        return ts.positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos);
+    }
+    ts.getStartPositionOfRange = getStartPositionOfRange;
+    /**
+     * Determines whether a name was originally the declaration name of an enum or namespace
+     * declaration.
+     */
+    function isDeclarationNameOfEnumOrNamespace(node) {
+        var parseNode = ts.getParseTreeNode(node);
+        if (parseNode) {
+            switch (parseNode.parent.kind) {
+                case 232 /* EnumDeclaration */:
+                case 233 /* ModuleDeclaration */:
+                    return parseNode === parseNode.parent.name;
+            }
+        }
+        return false;
+    }
+    ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace;
+    function getInitializedVariables(node) {
+        return ts.filter(node.declarations, isInitializedVariable);
+    }
+    ts.getInitializedVariables = getInitializedVariables;
+    function isInitializedVariable(node) {
+        return node.initializer !== undefined;
+    }
+    function isWatchSet(options) {
+        // Firefox has Object.prototype.watch
+        return options.watch && options.hasOwnProperty("watch");
+    }
+    ts.isWatchSet = isWatchSet;
+    function getCheckFlags(symbol) {
+        return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0;
+    }
+    ts.getCheckFlags = getCheckFlags;
+    function getDeclarationModifierFlagsFromSymbol(s) {
+        if (s.valueDeclaration) {
+            var flags = ts.getCombinedModifierFlags(s.valueDeclaration);
+            return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */;
+        }
+        if (getCheckFlags(s) & 6 /* Synthetic */) {
+            var checkFlags = s.checkFlags;
+            var accessModifier = checkFlags & 256 /* ContainsPrivate */ ? 8 /* Private */ :
+                checkFlags & 64 /* ContainsPublic */ ? 4 /* Public */ :
+                    16 /* Protected */;
+            var staticModifier = checkFlags & 512 /* ContainsStatic */ ? 32 /* Static */ : 0;
+            return accessModifier | staticModifier;
+        }
+        if (s.flags & 4194304 /* Prototype */) {
+            return 4 /* Public */ | 32 /* Static */;
+        }
+        return 0;
+    }
+    ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol;
+    function levenshtein(s1, s2) {
+        var previous = new Array(s2.length + 1);
+        var current = new Array(s2.length + 1);
+        for (var i = 0; i < s2.length + 1; i++) {
+            previous[i] = i;
+            current[i] = -1;
+        }
+        for (var i = 1; i < s1.length + 1; i++) {
+            current[0] = i;
+            for (var j = 1; j < s2.length + 1; j++) {
+                current[j] = Math.min(previous[j] + 1, current[j - 1] + 1, previous[j - 1] + (s1[i - 1] === s2[j - 1] ? 0 : 2));
+            }
+            // shift current back to previous, and then reuse previous' array
+            var tmp = previous;
+            previous = current;
+            current = tmp;
+        }
+        return previous[previous.length - 1];
+    }
+    ts.levenshtein = levenshtein;
+    function skipAlias(symbol, checker) {
+        return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol;
+    }
+    ts.skipAlias = skipAlias;
+    /** See comment on `declareModuleMember` in `binder.ts`. */
+    function getCombinedLocalAndExportSymbolFlags(symbol) {
+        return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
+    }
+    ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags;
+    function isWriteOnlyAccess(node) {
+        return accessKind(node) === 1 /* Write */;
+    }
+    ts.isWriteOnlyAccess = isWriteOnlyAccess;
+    function isWriteAccess(node) {
+        return accessKind(node) !== 0 /* Read */;
+    }
+    ts.isWriteAccess = isWriteAccess;
+    var AccessKind;
+    (function (AccessKind) {
+        /** Only reads from a variable. */
+        AccessKind[AccessKind["Read"] = 0] = "Read";
+        /** Only writes to a variable without using the result. E.g.: `x++;`. */
+        AccessKind[AccessKind["Write"] = 1] = "Write";
+        /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
+        AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
+    })(AccessKind || (AccessKind = {}));
+    function accessKind(node) {
+        var parent = node.parent;
+        if (!parent)
+            return 0 /* Read */;
+        switch (parent.kind) {
+            case 193 /* PostfixUnaryExpression */:
+            case 192 /* PrefixUnaryExpression */:
+                var operator = parent.operator;
+                return operator === 43 /* PlusPlusToken */ || operator === 44 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */;
+            case 194 /* BinaryExpression */:
+                var _a = parent, left = _a.left, operatorToken = _a.operatorToken;
+                return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : 0 /* Read */;
+            case 179 /* PropertyAccessExpression */:
+                return parent.name !== node ? 0 /* Read */ : accessKind(parent);
+            default:
+                return 0 /* Read */;
+        }
+        function writeOrReadWrite() {
+            // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
+            return parent.parent && parent.parent.kind === 210 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */;
+        }
+    }
+    function compareDataObjects(dst, src) {
+        if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
+            return false;
+        }
+        for (var e in dst) {
+            if (typeof dst[e] === "object") {
+                if (!compareDataObjects(dst[e], src[e])) {
+                    return false;
+                }
+            }
+            else if (typeof dst[e] !== "function") {
+                if (dst[e] !== src[e]) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    ts.compareDataObjects = compareDataObjects;
+    /**
+     * clears already present map by calling onDeleteExistingValue callback before deleting that key/value
+     */
+    function clearMap(map, onDeleteValue) {
+        // Remove all
+        map.forEach(onDeleteValue);
+        map.clear();
+    }
+    ts.clearMap = clearMap;
+    /**
+     * Mutates the map with newMap such that keys in map will be same as newMap.
+     */
+    function mutateMap(map, newMap, options) {
+        var createNewValue = options.createNewValue, onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue;
+        // Needs update
+        map.forEach(function (existingValue, key) {
+            var valueInNewMap = newMap.get(key);
+            // Not present any more in new map, remove it
+            if (valueInNewMap === undefined) {
+                map.delete(key);
+                onDeleteValue(existingValue, key);
+            }
+            else if (onExistingValue) {
+                onExistingValue(existingValue, valueInNewMap, key);
+            }
+        });
+        // Add new values that are not already present
+        newMap.forEach(function (valueInNewMap, key) {
+            if (!map.has(key)) {
+                // New values
+                map.set(key, createNewValue(key, valueInNewMap));
+            }
+        });
+    }
+    ts.mutateMap = mutateMap;
+    /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
+    function forEachAncestorDirectory(directory, callback) {
+        while (true) {
+            var result = callback(directory);
+            if (result !== undefined) {
+                return result;
+            }
+            var parentPath = ts.getDirectoryPath(directory);
+            if (parentPath === directory) {
+                return undefined;
+            }
+            directory = parentPath;
+        }
+    }
+    ts.forEachAncestorDirectory = forEachAncestorDirectory;
+})(ts || (ts = {}));
+(function (ts) {
+    function getDefaultLibFileName(options) {
+        switch (options.target) {
+            case 5 /* ESNext */:
+                return "lib.esnext.full.d.ts";
+            case 4 /* ES2017 */:
+                return "lib.es2017.full.d.ts";
+            case 3 /* ES2016 */:
+                return "lib.es2016.full.d.ts";
+            case 2 /* ES2015 */:
+                return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
+            default:
+                return "lib.d.ts";
+        }
+    }
+    ts.getDefaultLibFileName = getDefaultLibFileName;
+    function textSpanEnd(span) {
+        return span.start + span.length;
+    }
+    ts.textSpanEnd = textSpanEnd;
+    function textSpanIsEmpty(span) {
+        return span.length === 0;
+    }
+    ts.textSpanIsEmpty = textSpanIsEmpty;
+    function textSpanContainsPosition(span, position) {
+        return position >= span.start && position < textSpanEnd(span);
+    }
+    ts.textSpanContainsPosition = textSpanContainsPosition;
+    // Returns true if 'span' contains 'other'.
+    function textSpanContainsTextSpan(span, other) {
+        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
+    }
+    ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
+    function textSpanOverlapsWith(span, other) {
+        var overlapStart = Math.max(span.start, other.start);
+        var overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
+        return overlapStart < overlapEnd;
+    }
+    ts.textSpanOverlapsWith = textSpanOverlapsWith;
+    function textSpanOverlap(span1, span2) {
+        var overlapStart = Math.max(span1.start, span2.start);
+        var overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
+        if (overlapStart < overlapEnd) {
+            return createTextSpanFromBounds(overlapStart, overlapEnd);
+        }
+        return undefined;
+    }
+    ts.textSpanOverlap = textSpanOverlap;
+    function textSpanIntersectsWithTextSpan(span, other) {
+        return other.start <= textSpanEnd(span) && textSpanEnd(other) >= span.start;
+    }
+    ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
+    function textSpanIntersectsWith(span, start, length) {
+        var end = start + length;
+        return start <= textSpanEnd(span) && end >= span.start;
+    }
+    ts.textSpanIntersectsWith = textSpanIntersectsWith;
+    function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
+        var end1 = start1 + length1;
+        var end2 = start2 + length2;
+        return start2 <= end1 && end2 >= start1;
+    }
+    ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
+    function textSpanIntersectsWithPosition(span, position) {
+        return position <= textSpanEnd(span) && position >= span.start;
+    }
+    ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
+    function textSpanIntersection(span1, span2) {
+        var intersectStart = Math.max(span1.start, span2.start);
+        var intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
+        if (intersectStart <= intersectEnd) {
+            return createTextSpanFromBounds(intersectStart, intersectEnd);
+        }
+        return undefined;
+    }
+    ts.textSpanIntersection = textSpanIntersection;
+    function createTextSpan(start, length) {
+        if (start < 0) {
+            throw new Error("start < 0");
+        }
+        if (length < 0) {
+            throw new Error("length < 0");
+        }
+        return { start: start, length: length };
+    }
+    ts.createTextSpan = createTextSpan;
+    function createTextSpanFromBounds(start, end) {
+        return createTextSpan(start, end - start);
+    }
+    ts.createTextSpanFromBounds = createTextSpanFromBounds;
+    function textChangeRangeNewSpan(range) {
+        return createTextSpan(range.span.start, range.newLength);
+    }
+    ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
+    function textChangeRangeIsUnchanged(range) {
+        return textSpanIsEmpty(range.span) && range.newLength === 0;
+    }
+    ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
+    function createTextChangeRange(span, newLength) {
+        if (newLength < 0) {
+            throw new Error("newLength < 0");
+        }
+        return { span: span, newLength: newLength };
+    }
+    ts.createTextChangeRange = createTextChangeRange;
+    ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0);
+    /**
+     * Called to merge all the changes that occurred across several versions of a script snapshot
+     * into a single change.  i.e. if a user keeps making successive edits to a script we will
+     * have a text change from V1 to V2, V2 to V3, ..., Vn.
+     *
+     * This function will then merge those changes into a single change range valid between V1 and
+     * Vn.
+     */
+    function collapseTextChangeRangesAcrossMultipleVersions(changes) {
+        if (changes.length === 0) {
+            return ts.unchangedTextChangeRange;
+        }
+        if (changes.length === 1) {
+            return changes[0];
+        }
+        // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
+        // as it makes things much easier to reason about.
+        var change0 = changes[0];
+        var oldStartN = change0.span.start;
+        var oldEndN = textSpanEnd(change0.span);
+        var newEndN = oldStartN + change0.newLength;
+        for (var i = 1; i < changes.length; i++) {
+            var nextChange = changes[i];
+            // Consider the following case:
+            // i.e. two edits.  The first represents the text change range { { 10, 50 }, 30 }.  i.e. The span starting
+            // at 10, with length 50 is reduced to length 30.  The second represents the text change range { { 30, 30 }, 40 }.
+            // i.e. the span starting at 30 with length 30 is increased to length 40.
+            //
+            //      0         10        20        30        40        50        60        70        80        90        100
+            //      -------------------------------------------------------------------------------------------------------
+            //                |                                                 /
+            //                |                                            /----
+            //  T1            |                                       /----
+            //                |                                  /----
+            //                |                             /----
+            //      -------------------------------------------------------------------------------------------------------
+            //                                     |                            \
+            //                                     |                               \
+            //   T2                                |                                 \
+            //                                     |                                   \
+            //                                     |                                      \
+            //      -------------------------------------------------------------------------------------------------------
+            //
+            // Merging these turns out to not be too difficult.  First, determining the new start of the change is trivial
+            // it's just the min of the old and new starts.  i.e.:
+            //
+            //      0         10        20        30        40        50        60        70        80        90        100
+            //      ------------------------------------------------------------*------------------------------------------
+            //                |                                                 /
+            //                |                                            /----
+            //  T1            |                                       /----
+            //                |                                  /----
+            //                |                             /----
+            //      ----------------------------------------$-------------------$------------------------------------------
+            //                .                    |                            \
+            //                .                    |                               \
+            //   T2           .                    |                                 \
+            //                .                    |                                   \
+            //                .                    |                                      \
+            //      ----------------------------------------------------------------------*--------------------------------
+            //
+            // (Note the dots represent the newly inferred start.
+            // Determining the new and old end is also pretty simple.  Basically it boils down to paying attention to the
+            // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see
+            // which if the two $'s precedes the other, and we move that one forward until they line up.  in this case that
+            // means:
+            //
+            //      0         10        20        30        40        50        60        70        80        90        100
+            //      --------------------------------------------------------------------------------*----------------------
+            //                |                                                                     /
+            //                |                                                                /----
+            //  T1            |                                                           /----
+            //                |                                                      /----
+            //                |                                                 /----
+            //      ------------------------------------------------------------$------------------------------------------
+            //                .                    |                            \
+            //                .                    |                               \
+            //   T2           .                    |                                 \
+            //                .                    |                                   \
+            //                .                    |                                      \
+            //      ----------------------------------------------------------------------*--------------------------------
+            //
+            // In other words (in this case), we're recognizing that the second edit happened after where the first edit
+            // ended with a delta of 20 characters (60 - 40).  Thus, if we go back in time to where the first edit started
+            // that's the same as if we started at char 80 instead of 60.
+            //
+            // As it so happens, the same logic applies if the second edit precedes the first edit.  In that case rather
+            // than pushing the first edit forward to match the second, we'll push the second edit forward to match the
+            // first.
+            //
+            // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange
+            // semantics: { { start: 10, length: 70 }, newLength: 60 }
+            //
+            // The math then works out as follows.
+            // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the
+            // final result like so:
+            //
+            // {
+            //      oldStart3: Min(oldStart1, oldStart2),
+            //      oldEnd3  : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
+            //      newEnd3  : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
+            // }
+            var oldStart1 = oldStartN;
+            var oldEnd1 = oldEndN;
+            var newEnd1 = newEndN;
+            var oldStart2 = nextChange.span.start;
+            var oldEnd2 = textSpanEnd(nextChange.span);
+            var newEnd2 = oldStart2 + nextChange.newLength;
+            oldStartN = Math.min(oldStart1, oldStart2);
+            oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
+            newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
+        }
+        return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
+    }
+    ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
+    function getTypeParameterOwner(d) {
+        if (d && d.kind === 145 /* TypeParameter */) {
+            for (var current = d; current; current = current.parent) {
+                if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 230 /* InterfaceDeclaration */) {
+                    return current;
+                }
+            }
+        }
+    }
+    ts.getTypeParameterOwner = getTypeParameterOwner;
+    function isParameterPropertyDeclaration(node) {
+        return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 152 /* Constructor */ && ts.isClassLike(node.parent.parent);
+    }
+    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
+    function isEmptyBindingPattern(node) {
+        if (ts.isBindingPattern(node)) {
+            return ts.every(node.elements, isEmptyBindingElement);
+        }
+        return false;
+    }
+    ts.isEmptyBindingPattern = isEmptyBindingPattern;
+    function isEmptyBindingElement(node) {
+        if (ts.isOmittedExpression(node)) {
+            return true;
+        }
+        return isEmptyBindingPattern(node.name);
+    }
+    ts.isEmptyBindingElement = isEmptyBindingElement;
+    function walkUpBindingElementsAndPatterns(node) {
+        while (node && (node.kind === 176 /* BindingElement */ || ts.isBindingPattern(node))) {
+            node = node.parent;
+        }
+        return node;
+    }
+    function getCombinedModifierFlags(node) {
+        node = walkUpBindingElementsAndPatterns(node);
+        var flags = ts.getModifierFlags(node);
+        if (node.kind === 226 /* VariableDeclaration */) {
+            node = node.parent;
+        }
+        if (node && node.kind === 227 /* VariableDeclarationList */) {
+            flags |= ts.getModifierFlags(node);
+            node = node.parent;
+        }
+        if (node && node.kind === 208 /* VariableStatement */) {
+            flags |= ts.getModifierFlags(node);
+        }
+        return flags;
+    }
+    ts.getCombinedModifierFlags = getCombinedModifierFlags;
+    // Returns the node flags for this node and all relevant parent nodes.  This is done so that
+    // nodes like variable declarations and binding elements can returned a view of their flags
+    // that includes the modifiers from their container.  i.e. flags like export/declare aren't
+    // stored on the variable declaration directly, but on the containing variable statement
+    // (if it has one).  Similarly, flags for let/const are store on the variable declaration
+    // list.  By calling this function, all those flags are combined so that the client can treat
+    // the node as if it actually had those flags.
+    function getCombinedNodeFlags(node) {
+        node = walkUpBindingElementsAndPatterns(node);
+        var flags = node.flags;
+        if (node.kind === 226 /* VariableDeclaration */) {
+            node = node.parent;
+        }
+        if (node && node.kind === 227 /* VariableDeclarationList */) {
+            flags |= node.flags;
+            node = node.parent;
+        }
+        if (node && node.kind === 208 /* VariableStatement */) {
+            flags |= node.flags;
+        }
+        return flags;
+    }
+    ts.getCombinedNodeFlags = getCombinedNodeFlags;
+    /**
+     * Checks to see if the locale is in the appropriate format,
+     * and if it is, attempts to set the appropriate language.
+     */
+    function validateLocaleAndSetLanguage(locale, sys, errors) {
+        var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
+        if (!matchResult) {
+            if (errors) {
+                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
+            }
+            return;
+        }
+        var language = matchResult[1];
+        var territory = matchResult[3];
+        // First try the entire locale, then fall back to just language if that's all we have.
+        // Either ways do not fail, and fallback to the English diagnostic strings.
+        if (!trySetLanguageAndTerritory(language, territory, errors)) {
+            trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
+        }
+        function trySetLanguageAndTerritory(language, territory, errors) {
+            var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath());
+            var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath);
+            var filePath = ts.combinePaths(containingDirectoryPath, language);
+            if (territory) {
+                filePath = filePath + "-" + territory;
+            }
+            filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json"));
+            if (!sys.fileExists(filePath)) {
+                return false;
+            }
+            // TODO: Add codePage support for readFile?
+            var fileContents = "";
+            try {
+                fileContents = sys.readFile(filePath);
+            }
+            catch (e) {
+                if (errors) {
+                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath));
+                }
+                return false;
+            }
+            try {
+                ts.localizedDiagnosticMessages = JSON.parse(fileContents);
+            }
+            catch (e) {
+                if (errors) {
+                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath));
+                }
+                return false;
+            }
+            return true;
+        }
+    }
+    ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage;
+    function getOriginalNode(node, nodeTest) {
+        if (node) {
+            while (node.original !== undefined) {
+                node = node.original;
+            }
+        }
+        return !nodeTest || nodeTest(node) ? node : undefined;
+    }
+    ts.getOriginalNode = getOriginalNode;
+    /**
+     * Gets a value indicating whether a node originated in the parse tree.
+     *
+     * @param node The node to test.
+     */
+    function isParseTreeNode(node) {
+        return (node.flags & 8 /* Synthesized */) === 0;
+    }
+    ts.isParseTreeNode = isParseTreeNode;
+    function getParseTreeNode(node, nodeTest) {
+        if (node === undefined || isParseTreeNode(node)) {
+            return node;
+        }
+        node = getOriginalNode(node);
+        if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
+            return node;
+        }
+        return undefined;
+    }
+    ts.getParseTreeNode = getParseTreeNode;
+    /**
+     * Remove extra underscore from escaped identifier text content.
+     *
+     * @param identifier The escaped identifier text.
+     * @returns The unescaped identifier text.
+     */
+    function unescapeLeadingUnderscores(identifier) {
+        var id = identifier;
+        return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id;
+    }
+    ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores;
+    function idText(identifier) {
+        return unescapeLeadingUnderscores(identifier.escapedText);
+    }
+    ts.idText = idText;
+    function symbolName(symbol) {
+        return unescapeLeadingUnderscores(symbol.escapedName);
+    }
+    ts.symbolName = symbolName;
+    /**
+     * Remove extra underscore from escaped identifier text content.
+     * @deprecated Use `id.text` for the unescaped text.
+     * @param identifier The escaped identifier text.
+     * @returns The unescaped identifier text.
+     */
+    function unescapeIdentifier(id) {
+        return id;
+    }
+    ts.unescapeIdentifier = unescapeIdentifier;
+    /**
+     * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
+     * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
+     * will be merged with)
+     */
+    function nameForNamelessJSDocTypedef(declaration) {
+        var hostNode = declaration.parent.parent;
+        if (!hostNode) {
+            return undefined;
+        }
+        // Covers classes, functions - any named declaration host node
+        if (ts.isDeclaration(hostNode)) {
+            return getDeclarationIdentifier(hostNode);
+        }
+        // Covers remaining cases
+        switch (hostNode.kind) {
+            case 208 /* VariableStatement */:
+                if (hostNode.declarationList &&
+                    hostNode.declarationList.declarations[0]) {
+                    return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
+                }
+                return undefined;
+            case 210 /* ExpressionStatement */:
+                var expr = hostNode.expression;
+                switch (expr.kind) {
+                    case 179 /* PropertyAccessExpression */:
+                        return expr.name;
+                    case 180 /* ElementAccessExpression */:
+                        var arg = expr.argumentExpression;
+                        if (ts.isIdentifier(arg)) {
+                            return arg;
+                        }
+                }
+                return undefined;
+            case 1 /* EndOfFileToken */:
+                return undefined;
+            case 185 /* ParenthesizedExpression */: {
+                return getDeclarationIdentifier(hostNode.expression);
+            }
+            case 222 /* LabeledStatement */: {
+                if (ts.isDeclaration(hostNode.statement) || ts.isExpression(hostNode.statement)) {
+                    return getDeclarationIdentifier(hostNode.statement);
+                }
+                return undefined;
+            }
+            default:
+                ts.Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
+        }
+    }
+    function getDeclarationIdentifier(node) {
+        var name = getNameOfDeclaration(node);
+        return ts.isIdentifier(name) ? name : undefined;
+    }
+    function getNameOfJSDocTypedef(declaration) {
+        return declaration.name || nameForNamelessJSDocTypedef(declaration);
+    }
+    ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef;
+    function getNameOfDeclaration(declaration) {
+        if (!declaration) {
+            return undefined;
+        }
+        switch (declaration.kind) {
+            case 284 /* JSDocPropertyTag */:
+            case 279 /* JSDocParameterTag */: {
+                var name = declaration.name;
+                if (name.kind === 143 /* QualifiedName */) {
+                    return name.right;
+                }
+                break;
+            }
+            case 194 /* BinaryExpression */: {
+                var expr = declaration;
+                switch (ts.getSpecialPropertyAssignmentKind(expr)) {
+                    case 1 /* ExportsProperty */:
+                    case 4 /* ThisProperty */:
+                    case 5 /* Property */:
+                    case 3 /* PrototypeProperty */:
+                        return expr.left.name;
+                    default:
+                        return undefined;
+                }
+            }
+            case 283 /* JSDocTypedefTag */:
+                return getNameOfJSDocTypedef(declaration);
+            case 243 /* ExportAssignment */: {
+                var expression = declaration.expression;
+                return ts.isIdentifier(expression) ? expression : undefined;
+            }
+        }
+        return declaration.name;
+    }
+    ts.getNameOfDeclaration = getNameOfDeclaration;
+    /**
+     * Gets the JSDoc parameter tags for the node if present.
+     *
+     * @remarks Returns any JSDoc param tag that matches the provided
+     * parameter, whether a param tag on a containing function
+     * expression, or a param tag on a variable declaration whose
+     * initializer is the containing function. The tags closest to the
+     * node are returned first, so in the previous example, the param
+     * tag on the containing function expression would be first.
+     *
+     * Does not return tags for binding patterns, because JSDoc matches
+     * parameters by name and binding patterns do not have a name.
+     */
+    function getJSDocParameterTags(param) {
+        if (param.name && ts.isIdentifier(param.name)) {
+            var name_1 = param.name.escapedText;
+            return getJSDocTags(param.parent).filter(function (tag) { return ts.isJSDocParameterTag(tag) && ts.isIdentifier(tag.name) && tag.name.escapedText === name_1; });
+        }
+        // a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name
+        return undefined;
+    }
+    ts.getJSDocParameterTags = getJSDocParameterTags;
+    /**
+     * Return true if the node has JSDoc parameter tags.
+     *
+     * @remarks Includes parameter tags that are not directly on the node,
+     * for example on a variable declaration whose initializer is a function expression.
+     */
+    function hasJSDocParameterTags(node) {
+        return !!getFirstJSDocTag(node, 279 /* JSDocParameterTag */);
+    }
+    ts.hasJSDocParameterTags = hasJSDocParameterTags;
+    /** Gets the JSDoc augments tag for the node if present */
+    function getJSDocAugmentsTag(node) {
+        return getFirstJSDocTag(node, 277 /* JSDocAugmentsTag */);
+    }
+    ts.getJSDocAugmentsTag = getJSDocAugmentsTag;
+    /** Gets the JSDoc class tag for the node if present */
+    function getJSDocClassTag(node) {
+        return getFirstJSDocTag(node, 278 /* JSDocClassTag */);
+    }
+    ts.getJSDocClassTag = getJSDocClassTag;
+    /** Gets the JSDoc return tag for the node if present */
+    function getJSDocReturnTag(node) {
+        return getFirstJSDocTag(node, 280 /* JSDocReturnTag */);
+    }
+    ts.getJSDocReturnTag = getJSDocReturnTag;
+    /** Gets the JSDoc template tag for the node if present */
+    function getJSDocTemplateTag(node) {
+        return getFirstJSDocTag(node, 282 /* JSDocTemplateTag */);
+    }
+    ts.getJSDocTemplateTag = getJSDocTemplateTag;
+    /** Gets the JSDoc type tag for the node if present and valid */
+    function getJSDocTypeTag(node) {
+        // We should have already issued an error if there were multiple type jsdocs, so just use the first one.
+        var tag = getFirstJSDocTag(node, 281 /* JSDocTypeTag */);
+        if (tag && tag.typeExpression && tag.typeExpression.type) {
+            return tag;
+        }
+        return undefined;
+    }
+    ts.getJSDocTypeTag = getJSDocTypeTag;
+    /**
+     * Gets the type node for the node if provided via JSDoc.
+     *
+     * @remarks The search includes any JSDoc param tag that relates
+     * to the provided parameter, for example a type tag on the
+     * parameter itself, or a param tag on a containing function
+     * expression, or a param tag on a variable declaration whose
+     * initializer is the containing function. The tags closest to the
+     * node are examined first, so in the previous example, the type
+     * tag directly on the node would be returned.
+     */
+    function getJSDocType(node) {
+        var tag = getFirstJSDocTag(node, 281 /* JSDocTypeTag */);
+        if (!tag && node.kind === 146 /* Parameter */) {
+            var paramTags = getJSDocParameterTags(node);
+            if (paramTags) {
+                tag = ts.find(paramTags, function (tag) { return !!tag.typeExpression; });
+            }
+        }
+        return tag && tag.typeExpression && tag.typeExpression.type;
+    }
+    ts.getJSDocType = getJSDocType;
+    /**
+     * Gets the return type node for the node if provided via JSDoc's return tag.
+     *
+     * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
+     * gets the type from inside the braces.
+     */
+    function getJSDocReturnType(node) {
+        var returnTag = getJSDocReturnTag(node);
+        return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
+    }
+    ts.getJSDocReturnType = getJSDocReturnType;
+    /** Get all JSDoc tags related to a node, including those on parent nodes. */
+    function getJSDocTags(node) {
+        var tags = node.jsDocCache;
+        // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
+        if (tags === undefined) {
+            node.jsDocCache = tags = ts.flatMap(ts.getJSDocCommentsAndTags(node), function (j) { return ts.isJSDoc(j) ? j.tags : j; });
+        }
+        return tags;
+    }
+    ts.getJSDocTags = getJSDocTags;
+    /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
+    function getFirstJSDocTag(node, kind) {
+        var tags = getJSDocTags(node);
+        return ts.find(tags, function (doc) { return doc.kind === kind; });
+    }
+    /** Gets all JSDoc tags of a specified kind, or undefined if not present. */
+    function getAllJSDocTagsOfKind(node, kind) {
+        var tags = getJSDocTags(node);
+        return ts.filter(tags, function (doc) { return doc.kind === kind; });
+    }
+    ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind;
+})(ts || (ts = {}));
+// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
+(function (ts) {
+    // Literals
+    function isNumericLiteral(node) {
+        return node.kind === 8 /* NumericLiteral */;
+    }
+    ts.isNumericLiteral = isNumericLiteral;
+    function isStringLiteral(node) {
+        return node.kind === 9 /* StringLiteral */;
+    }
+    ts.isStringLiteral = isStringLiteral;
+    function isJsxText(node) {
+        return node.kind === 10 /* JsxText */;
+    }
+    ts.isJsxText = isJsxText;
+    function isRegularExpressionLiteral(node) {
+        return node.kind === 12 /* RegularExpressionLiteral */;
+    }
+    ts.isRegularExpressionLiteral = isRegularExpressionLiteral;
+    function isNoSubstitutionTemplateLiteral(node) {
+        return node.kind === 13 /* NoSubstitutionTemplateLiteral */;
+    }
+    ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral;
+    // Pseudo-literals
+    function isTemplateHead(node) {
+        return node.kind === 14 /* TemplateHead */;
+    }
+    ts.isTemplateHead = isTemplateHead;
+    function isTemplateMiddle(node) {
+        return node.kind === 15 /* TemplateMiddle */;
+    }
+    ts.isTemplateMiddle = isTemplateMiddle;
+    function isTemplateTail(node) {
+        return node.kind === 16 /* TemplateTail */;
+    }
+    ts.isTemplateTail = isTemplateTail;
+    function isIdentifier(node) {
+        return node.kind === 71 /* Identifier */;
+    }
+    ts.isIdentifier = isIdentifier;
+    // Names
+    function isQualifiedName(node) {
+        return node.kind === 143 /* QualifiedName */;
+    }
+    ts.isQualifiedName = isQualifiedName;
+    function isComputedPropertyName(node) {
+        return node.kind === 144 /* ComputedPropertyName */;
+    }
+    ts.isComputedPropertyName = isComputedPropertyName;
+    // Signature elements
+    function isTypeParameterDeclaration(node) {
+        return node.kind === 145 /* TypeParameter */;
+    }
+    ts.isTypeParameterDeclaration = isTypeParameterDeclaration;
+    function isParameter(node) {
+        return node.kind === 146 /* Parameter */;
+    }
+    ts.isParameter = isParameter;
+    function isDecorator(node) {
+        return node.kind === 147 /* Decorator */;
+    }
+    ts.isDecorator = isDecorator;
+    // TypeMember
+    function isPropertySignature(node) {
+        return node.kind === 148 /* PropertySignature */;
+    }
+    ts.isPropertySignature = isPropertySignature;
+    function isPropertyDeclaration(node) {
+        return node.kind === 149 /* PropertyDeclaration */;
+    }
+    ts.isPropertyDeclaration = isPropertyDeclaration;
+    function isMethodSignature(node) {
+        return node.kind === 150 /* MethodSignature */;
+    }
+    ts.isMethodSignature = isMethodSignature;
+    function isMethodDeclaration(node) {
+        return node.kind === 151 /* MethodDeclaration */;
+    }
+    ts.isMethodDeclaration = isMethodDeclaration;
+    function isConstructorDeclaration(node) {
+        return node.kind === 152 /* Constructor */;
+    }
+    ts.isConstructorDeclaration = isConstructorDeclaration;
+    function isGetAccessorDeclaration(node) {
+        return node.kind === 153 /* GetAccessor */;
+    }
+    ts.isGetAccessorDeclaration = isGetAccessorDeclaration;
+    function isSetAccessorDeclaration(node) {
+        return node.kind === 154 /* SetAccessor */;
+    }
+    ts.isSetAccessorDeclaration = isSetAccessorDeclaration;
+    function isCallSignatureDeclaration(node) {
+        return node.kind === 155 /* CallSignature */;
+    }
+    ts.isCallSignatureDeclaration = isCallSignatureDeclaration;
+    function isConstructSignatureDeclaration(node) {
+        return node.kind === 156 /* ConstructSignature */;
+    }
+    ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration;
+    function isIndexSignatureDeclaration(node) {
+        return node.kind === 157 /* IndexSignature */;
+    }
+    ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration;
+    // Type
+    function isTypePredicateNode(node) {
+        return node.kind === 158 /* TypePredicate */;
+    }
+    ts.isTypePredicateNode = isTypePredicateNode;
+    function isTypeReferenceNode(node) {
+        return node.kind === 159 /* TypeReference */;
+    }
+    ts.isTypeReferenceNode = isTypeReferenceNode;
+    function isFunctionTypeNode(node) {
+        return node.kind === 160 /* FunctionType */;
+    }
+    ts.isFunctionTypeNode = isFunctionTypeNode;
+    function isConstructorTypeNode(node) {
+        return node.kind === 161 /* ConstructorType */;
+    }
+    ts.isConstructorTypeNode = isConstructorTypeNode;
+    function isTypeQueryNode(node) {
+        return node.kind === 162 /* TypeQuery */;
+    }
+    ts.isTypeQueryNode = isTypeQueryNode;
+    function isTypeLiteralNode(node) {
+        return node.kind === 163 /* TypeLiteral */;
+    }
+    ts.isTypeLiteralNode = isTypeLiteralNode;
+    function isArrayTypeNode(node) {
+        return node.kind === 164 /* ArrayType */;
+    }
+    ts.isArrayTypeNode = isArrayTypeNode;
+    function isTupleTypeNode(node) {
+        return node.kind === 165 /* TupleType */;
+    }
+    ts.isTupleTypeNode = isTupleTypeNode;
+    function isUnionTypeNode(node) {
+        return node.kind === 166 /* UnionType */;
+    }
+    ts.isUnionTypeNode = isUnionTypeNode;
+    function isIntersectionTypeNode(node) {
+        return node.kind === 167 /* IntersectionType */;
+    }
+    ts.isIntersectionTypeNode = isIntersectionTypeNode;
+    function isParenthesizedTypeNode(node) {
+        return node.kind === 168 /* ParenthesizedType */;
+    }
+    ts.isParenthesizedTypeNode = isParenthesizedTypeNode;
+    function isThisTypeNode(node) {
+        return node.kind === 169 /* ThisType */;
+    }
+    ts.isThisTypeNode = isThisTypeNode;
+    function isTypeOperatorNode(node) {
+        return node.kind === 170 /* TypeOperator */;
+    }
+    ts.isTypeOperatorNode = isTypeOperatorNode;
+    function isIndexedAccessTypeNode(node) {
+        return node.kind === 171 /* IndexedAccessType */;
+    }
+    ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode;
+    function isMappedTypeNode(node) {
+        return node.kind === 172 /* MappedType */;
+    }
+    ts.isMappedTypeNode = isMappedTypeNode;
+    function isLiteralTypeNode(node) {
+        return node.kind === 173 /* LiteralType */;
+    }
+    ts.isLiteralTypeNode = isLiteralTypeNode;
+    // Binding patterns
+    function isObjectBindingPattern(node) {
+        return node.kind === 174 /* ObjectBindingPattern */;
+    }
+    ts.isObjectBindingPattern = isObjectBindingPattern;
+    function isArrayBindingPattern(node) {
+        return node.kind === 175 /* ArrayBindingPattern */;
+    }
+    ts.isArrayBindingPattern = isArrayBindingPattern;
+    function isBindingElement(node) {
+        return node.kind === 176 /* BindingElement */;
+    }
+    ts.isBindingElement = isBindingElement;
+    // Expression
+    function isArrayLiteralExpression(node) {
+        return node.kind === 177 /* ArrayLiteralExpression */;
+    }
+    ts.isArrayLiteralExpression = isArrayLiteralExpression;
+    function isObjectLiteralExpression(node) {
+        return node.kind === 178 /* ObjectLiteralExpression */;
+    }
+    ts.isObjectLiteralExpression = isObjectLiteralExpression;
+    function isPropertyAccessExpression(node) {
+        return node.kind === 179 /* PropertyAccessExpression */;
+    }
+    ts.isPropertyAccessExpression = isPropertyAccessExpression;
+    function isElementAccessExpression(node) {
+        return node.kind === 180 /* ElementAccessExpression */;
+    }
+    ts.isElementAccessExpression = isElementAccessExpression;
+    function isCallExpression(node) {
+        return node.kind === 181 /* CallExpression */;
+    }
+    ts.isCallExpression = isCallExpression;
+    function isNewExpression(node) {
+        return node.kind === 182 /* NewExpression */;
+    }
+    ts.isNewExpression = isNewExpression;
+    function isTaggedTemplateExpression(node) {
+        return node.kind === 183 /* TaggedTemplateExpression */;
+    }
+    ts.isTaggedTemplateExpression = isTaggedTemplateExpression;
+    function isTypeAssertion(node) {
+        return node.kind === 184 /* TypeAssertionExpression */;
+    }
+    ts.isTypeAssertion = isTypeAssertion;
+    function isParenthesizedExpression(node) {
+        return node.kind === 185 /* ParenthesizedExpression */;
+    }
+    ts.isParenthesizedExpression = isParenthesizedExpression;
+    function skipPartiallyEmittedExpressions(node) {
+        while (node.kind === 288 /* PartiallyEmittedExpression */) {
+            node = node.expression;
+        }
+        return node;
+    }
+    ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions;
+    function isFunctionExpression(node) {
+        return node.kind === 186 /* FunctionExpression */;
+    }
+    ts.isFunctionExpression = isFunctionExpression;
+    function isArrowFunction(node) {
+        return node.kind === 187 /* ArrowFunction */;
+    }
+    ts.isArrowFunction = isArrowFunction;
+    function isDeleteExpression(node) {
+        return node.kind === 188 /* DeleteExpression */;
+    }
+    ts.isDeleteExpression = isDeleteExpression;
+    function isTypeOfExpression(node) {
+        return node.kind === 191 /* AwaitExpression */;
+    }
+    ts.isTypeOfExpression = isTypeOfExpression;
+    function isVoidExpression(node) {
+        return node.kind === 190 /* VoidExpression */;
+    }
+    ts.isVoidExpression = isVoidExpression;
+    function isAwaitExpression(node) {
+        return node.kind === 191 /* AwaitExpression */;
+    }
+    ts.isAwaitExpression = isAwaitExpression;
+    function isPrefixUnaryExpression(node) {
+        return node.kind === 192 /* PrefixUnaryExpression */;
+    }
+    ts.isPrefixUnaryExpression = isPrefixUnaryExpression;
+    function isPostfixUnaryExpression(node) {
+        return node.kind === 193 /* PostfixUnaryExpression */;
+    }
+    ts.isPostfixUnaryExpression = isPostfixUnaryExpression;
+    function isBinaryExpression(node) {
+        return node.kind === 194 /* BinaryExpression */;
+    }
+    ts.isBinaryExpression = isBinaryExpression;
+    function isConditionalExpression(node) {
+        return node.kind === 195 /* ConditionalExpression */;
+    }
+    ts.isConditionalExpression = isConditionalExpression;
+    function isTemplateExpression(node) {
+        return node.kind === 196 /* TemplateExpression */;
+    }
+    ts.isTemplateExpression = isTemplateExpression;
+    function isYieldExpression(node) {
+        return node.kind === 197 /* YieldExpression */;
+    }
+    ts.isYieldExpression = isYieldExpression;
+    function isSpreadElement(node) {
+        return node.kind === 198 /* SpreadElement */;
+    }
+    ts.isSpreadElement = isSpreadElement;
+    function isClassExpression(node) {
+        return node.kind === 199 /* ClassExpression */;
+    }
+    ts.isClassExpression = isClassExpression;
+    function isOmittedExpression(node) {
+        return node.kind === 200 /* OmittedExpression */;
+    }
+    ts.isOmittedExpression = isOmittedExpression;
+    function isExpressionWithTypeArguments(node) {
+        return node.kind === 201 /* ExpressionWithTypeArguments */;
+    }
+    ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments;
+    function isAsExpression(node) {
+        return node.kind === 202 /* AsExpression */;
+    }
+    ts.isAsExpression = isAsExpression;
+    function isNonNullExpression(node) {
+        return node.kind === 203 /* NonNullExpression */;
+    }
+    ts.isNonNullExpression = isNonNullExpression;
+    function isMetaProperty(node) {
+        return node.kind === 204 /* MetaProperty */;
+    }
+    ts.isMetaProperty = isMetaProperty;
+    // Misc
+    function isTemplateSpan(node) {
+        return node.kind === 205 /* TemplateSpan */;
+    }
+    ts.isTemplateSpan = isTemplateSpan;
+    function isSemicolonClassElement(node) {
+        return node.kind === 206 /* SemicolonClassElement */;
+    }
+    ts.isSemicolonClassElement = isSemicolonClassElement;
+    // Block
+    function isBlock(node) {
+        return node.kind === 207 /* Block */;
+    }
+    ts.isBlock = isBlock;
+    function isVariableStatement(node) {
+        return node.kind === 208 /* VariableStatement */;
+    }
+    ts.isVariableStatement = isVariableStatement;
+    function isEmptyStatement(node) {
+        return node.kind === 209 /* EmptyStatement */;
+    }
+    ts.isEmptyStatement = isEmptyStatement;
+    function isExpressionStatement(node) {
+        return node.kind === 210 /* ExpressionStatement */;
+    }
+    ts.isExpressionStatement = isExpressionStatement;
+    function isIfStatement(node) {
+        return node.kind === 211 /* IfStatement */;
+    }
+    ts.isIfStatement = isIfStatement;
+    function isDoStatement(node) {
+        return node.kind === 212 /* DoStatement */;
+    }
+    ts.isDoStatement = isDoStatement;
+    function isWhileStatement(node) {
+        return node.kind === 213 /* WhileStatement */;
+    }
+    ts.isWhileStatement = isWhileStatement;
+    function isForStatement(node) {
+        return node.kind === 214 /* ForStatement */;
+    }
+    ts.isForStatement = isForStatement;
+    function isForInStatement(node) {
+        return node.kind === 215 /* ForInStatement */;
+    }
+    ts.isForInStatement = isForInStatement;
+    function isForOfStatement(node) {
+        return node.kind === 216 /* ForOfStatement */;
+    }
+    ts.isForOfStatement = isForOfStatement;
+    function isContinueStatement(node) {
+        return node.kind === 217 /* ContinueStatement */;
+    }
+    ts.isContinueStatement = isContinueStatement;
+    function isBreakStatement(node) {
+        return node.kind === 218 /* BreakStatement */;
+    }
+    ts.isBreakStatement = isBreakStatement;
+    function isReturnStatement(node) {
+        return node.kind === 219 /* ReturnStatement */;
+    }
+    ts.isReturnStatement = isReturnStatement;
+    function isWithStatement(node) {
+        return node.kind === 220 /* WithStatement */;
+    }
+    ts.isWithStatement = isWithStatement;
+    function isSwitchStatement(node) {
+        return node.kind === 221 /* SwitchStatement */;
+    }
+    ts.isSwitchStatement = isSwitchStatement;
+    function isLabeledStatement(node) {
+        return node.kind === 222 /* LabeledStatement */;
+    }
+    ts.isLabeledStatement = isLabeledStatement;
+    function isThrowStatement(node) {
+        return node.kind === 223 /* ThrowStatement */;
+    }
+    ts.isThrowStatement = isThrowStatement;
+    function isTryStatement(node) {
+        return node.kind === 224 /* TryStatement */;
+    }
+    ts.isTryStatement = isTryStatement;
+    function isDebuggerStatement(node) {
+        return node.kind === 225 /* DebuggerStatement */;
+    }
+    ts.isDebuggerStatement = isDebuggerStatement;
+    function isVariableDeclaration(node) {
+        return node.kind === 226 /* VariableDeclaration */;
+    }
+    ts.isVariableDeclaration = isVariableDeclaration;
+    function isVariableDeclarationList(node) {
+        return node.kind === 227 /* VariableDeclarationList */;
+    }
+    ts.isVariableDeclarationList = isVariableDeclarationList;
+    function isFunctionDeclaration(node) {
+        return node.kind === 228 /* FunctionDeclaration */;
+    }
+    ts.isFunctionDeclaration = isFunctionDeclaration;
+    function isClassDeclaration(node) {
+        return node.kind === 229 /* ClassDeclaration */;
+    }
+    ts.isClassDeclaration = isClassDeclaration;
+    function isInterfaceDeclaration(node) {
+        return node.kind === 230 /* InterfaceDeclaration */;
+    }
+    ts.isInterfaceDeclaration = isInterfaceDeclaration;
+    function isTypeAliasDeclaration(node) {
+        return node.kind === 231 /* TypeAliasDeclaration */;
+    }
+    ts.isTypeAliasDeclaration = isTypeAliasDeclaration;
+    function isEnumDeclaration(node) {
+        return node.kind === 232 /* EnumDeclaration */;
+    }
+    ts.isEnumDeclaration = isEnumDeclaration;
+    function isModuleDeclaration(node) {
+        return node.kind === 233 /* ModuleDeclaration */;
+    }
+    ts.isModuleDeclaration = isModuleDeclaration;
+    function isModuleBlock(node) {
+        return node.kind === 234 /* ModuleBlock */;
+    }
+    ts.isModuleBlock = isModuleBlock;
+    function isCaseBlock(node) {
+        return node.kind === 235 /* CaseBlock */;
+    }
+    ts.isCaseBlock = isCaseBlock;
+    function isNamespaceExportDeclaration(node) {
+        return node.kind === 236 /* NamespaceExportDeclaration */;
+    }
+    ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration;
+    function isImportEqualsDeclaration(node) {
+        return node.kind === 237 /* ImportEqualsDeclaration */;
+    }
+    ts.isImportEqualsDeclaration = isImportEqualsDeclaration;
+    function isImportDeclaration(node) {
+        return node.kind === 238 /* ImportDeclaration */;
+    }
+    ts.isImportDeclaration = isImportDeclaration;
+    function isImportClause(node) {
+        return node.kind === 239 /* ImportClause */;
+    }
+    ts.isImportClause = isImportClause;
+    function isNamespaceImport(node) {
+        return node.kind === 240 /* NamespaceImport */;
+    }
+    ts.isNamespaceImport = isNamespaceImport;
+    function isNamedImports(node) {
+        return node.kind === 241 /* NamedImports */;
+    }
+    ts.isNamedImports = isNamedImports;
+    function isImportSpecifier(node) {
+        return node.kind === 242 /* ImportSpecifier */;
+    }
+    ts.isImportSpecifier = isImportSpecifier;
+    function isExportAssignment(node) {
+        return node.kind === 243 /* ExportAssignment */;
+    }
+    ts.isExportAssignment = isExportAssignment;
+    function isExportDeclaration(node) {
+        return node.kind === 244 /* ExportDeclaration */;
+    }
+    ts.isExportDeclaration = isExportDeclaration;
+    function isNamedExports(node) {
+        return node.kind === 245 /* NamedExports */;
+    }
+    ts.isNamedExports = isNamedExports;
+    function isExportSpecifier(node) {
+        return node.kind === 246 /* ExportSpecifier */;
+    }
+    ts.isExportSpecifier = isExportSpecifier;
+    function isMissingDeclaration(node) {
+        return node.kind === 247 /* MissingDeclaration */;
+    }
+    ts.isMissingDeclaration = isMissingDeclaration;
+    // Module References
+    function isExternalModuleReference(node) {
+        return node.kind === 248 /* ExternalModuleReference */;
+    }
+    ts.isExternalModuleReference = isExternalModuleReference;
+    // JSX
+    function isJsxElement(node) {
+        return node.kind === 249 /* JsxElement */;
+    }
+    ts.isJsxElement = isJsxElement;
+    function isJsxSelfClosingElement(node) {
+        return node.kind === 250 /* JsxSelfClosingElement */;
+    }
+    ts.isJsxSelfClosingElement = isJsxSelfClosingElement;
+    function isJsxOpeningElement(node) {
+        return node.kind === 251 /* JsxOpeningElement */;
+    }
+    ts.isJsxOpeningElement = isJsxOpeningElement;
+    function isJsxClosingElement(node) {
+        return node.kind === 252 /* JsxClosingElement */;
+    }
+    ts.isJsxClosingElement = isJsxClosingElement;
+    function isJsxAttribute(node) {
+        return node.kind === 253 /* JsxAttribute */;
+    }
+    ts.isJsxAttribute = isJsxAttribute;
+    function isJsxAttributes(node) {
+        return node.kind === 254 /* JsxAttributes */;
+    }
+    ts.isJsxAttributes = isJsxAttributes;
+    function isJsxSpreadAttribute(node) {
+        return node.kind === 255 /* JsxSpreadAttribute */;
+    }
+    ts.isJsxSpreadAttribute = isJsxSpreadAttribute;
+    function isJsxExpression(node) {
+        return node.kind === 256 /* JsxExpression */;
+    }
+    ts.isJsxExpression = isJsxExpression;
+    // Clauses
+    function isCaseClause(node) {
+        return node.kind === 257 /* CaseClause */;
+    }
+    ts.isCaseClause = isCaseClause;
+    function isDefaultClause(node) {
+        return node.kind === 258 /* DefaultClause */;
+    }
+    ts.isDefaultClause = isDefaultClause;
+    function isHeritageClause(node) {
+        return node.kind === 259 /* HeritageClause */;
+    }
+    ts.isHeritageClause = isHeritageClause;
+    function isCatchClause(node) {
+        return node.kind === 260 /* CatchClause */;
+    }
+    ts.isCatchClause = isCatchClause;
+    // Property assignments
+    function isPropertyAssignment(node) {
+        return node.kind === 261 /* PropertyAssignment */;
+    }
+    ts.isPropertyAssignment = isPropertyAssignment;
+    function isShorthandPropertyAssignment(node) {
+        return node.kind === 262 /* ShorthandPropertyAssignment */;
+    }
+    ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment;
+    function isSpreadAssignment(node) {
+        return node.kind === 263 /* SpreadAssignment */;
+    }
+    ts.isSpreadAssignment = isSpreadAssignment;
+    // Enum
+    function isEnumMember(node) {
+        return node.kind === 264 /* EnumMember */;
+    }
+    ts.isEnumMember = isEnumMember;
+    // Top-level nodes
+    function isSourceFile(node) {
+        return node.kind === 265 /* SourceFile */;
+    }
+    ts.isSourceFile = isSourceFile;
+    function isBundle(node) {
+        return node.kind === 266 /* Bundle */;
+    }
+    ts.isBundle = isBundle;
+    // JSDoc
+    function isJSDocTypeExpression(node) {
+        return node.kind === 267 /* JSDocTypeExpression */;
+    }
+    ts.isJSDocTypeExpression = isJSDocTypeExpression;
+    function isJSDocAllType(node) {
+        return node.kind === 268 /* JSDocAllType */;
+    }
+    ts.isJSDocAllType = isJSDocAllType;
+    function isJSDocUnknownType(node) {
+        return node.kind === 269 /* JSDocUnknownType */;
+    }
+    ts.isJSDocUnknownType = isJSDocUnknownType;
+    function isJSDocNullableType(node) {
+        return node.kind === 270 /* JSDocNullableType */;
+    }
+    ts.isJSDocNullableType = isJSDocNullableType;
+    function isJSDocNonNullableType(node) {
+        return node.kind === 271 /* JSDocNonNullableType */;
+    }
+    ts.isJSDocNonNullableType = isJSDocNonNullableType;
+    function isJSDocOptionalType(node) {
+        return node.kind === 272 /* JSDocOptionalType */;
+    }
+    ts.isJSDocOptionalType = isJSDocOptionalType;
+    function isJSDocFunctionType(node) {
+        return node.kind === 273 /* JSDocFunctionType */;
+    }
+    ts.isJSDocFunctionType = isJSDocFunctionType;
+    function isJSDocVariadicType(node) {
+        return node.kind === 274 /* JSDocVariadicType */;
+    }
+    ts.isJSDocVariadicType = isJSDocVariadicType;
+    function isJSDoc(node) {
+        return node.kind === 275 /* JSDocComment */;
+    }
+    ts.isJSDoc = isJSDoc;
+    function isJSDocAugmentsTag(node) {
+        return node.kind === 277 /* JSDocAugmentsTag */;
+    }
+    ts.isJSDocAugmentsTag = isJSDocAugmentsTag;
+    function isJSDocParameterTag(node) {
+        return node.kind === 279 /* JSDocParameterTag */;
+    }
+    ts.isJSDocParameterTag = isJSDocParameterTag;
+    function isJSDocReturnTag(node) {
+        return node.kind === 280 /* JSDocReturnTag */;
+    }
+    ts.isJSDocReturnTag = isJSDocReturnTag;
+    function isJSDocTypeTag(node) {
+        return node.kind === 281 /* JSDocTypeTag */;
+    }
+    ts.isJSDocTypeTag = isJSDocTypeTag;
+    function isJSDocTemplateTag(node) {
+        return node.kind === 282 /* JSDocTemplateTag */;
+    }
+    ts.isJSDocTemplateTag = isJSDocTemplateTag;
+    function isJSDocTypedefTag(node) {
+        return node.kind === 283 /* JSDocTypedefTag */;
+    }
+    ts.isJSDocTypedefTag = isJSDocTypedefTag;
+    function isJSDocPropertyTag(node) {
+        return node.kind === 284 /* JSDocPropertyTag */;
+    }
+    ts.isJSDocPropertyTag = isJSDocPropertyTag;
+    function isJSDocPropertyLikeTag(node) {
+        return node.kind === 284 /* JSDocPropertyTag */ || node.kind === 279 /* JSDocParameterTag */;
+    }
+    ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag;
+    function isJSDocTypeLiteral(node) {
+        return node.kind === 285 /* JSDocTypeLiteral */;
+    }
+    ts.isJSDocTypeLiteral = isJSDocTypeLiteral;
+})(ts || (ts = {}));
+// Node tests
+//
+// All node tests in the following list should *not* reference parent pointers so that
+// they may be used with transformations.
+(function (ts) {
+    /* @internal */
+    function isSyntaxList(n) {
+        return n.kind === 286 /* SyntaxList */;
+    }
+    ts.isSyntaxList = isSyntaxList;
+    /* @internal */
+    function isNode(node) {
+        return isNodeKind(node.kind);
+    }
+    ts.isNode = isNode;
+    /* @internal */
+    function isNodeKind(kind) {
+        return kind >= 143 /* FirstNode */;
+    }
+    ts.isNodeKind = isNodeKind;
+    /**
+     * True if node is of some token syntax kind.
+     * For example, this is true for an IfKeyword but not for an IfStatement.
+     */
+    function isToken(n) {
+        return n.kind >= 0 /* FirstToken */ && n.kind <= 142 /* LastToken */;
+    }
+    ts.isToken = isToken;
+    // Node Arrays
+    /* @internal */
+    function isNodeArray(array) {
+        return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
+    }
+    ts.isNodeArray = isNodeArray;
+    // Literals
+    /* @internal */
+    function isLiteralKind(kind) {
+        return 8 /* FirstLiteralToken */ <= kind && kind <= 13 /* LastLiteralToken */;
+    }
+    ts.isLiteralKind = isLiteralKind;
+    function isLiteralExpression(node) {
+        return isLiteralKind(node.kind);
+    }
+    ts.isLiteralExpression = isLiteralExpression;
+    // Pseudo-literals
+    /* @internal */
+    function isTemplateLiteralKind(kind) {
+        return 13 /* FirstTemplateToken */ <= kind && kind <= 16 /* LastTemplateToken */;
+    }
+    ts.isTemplateLiteralKind = isTemplateLiteralKind;
+    function isTemplateMiddleOrTemplateTail(node) {
+        var kind = node.kind;
+        return kind === 15 /* TemplateMiddle */
+            || kind === 16 /* TemplateTail */;
+    }
+    ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail;
+    function isStringTextContainingNode(node) {
+        switch (node.kind) {
+            case 9 /* StringLiteral */:
+            case 14 /* TemplateHead */:
+            case 15 /* TemplateMiddle */:
+            case 16 /* TemplateTail */:
+            case 13 /* NoSubstitutionTemplateLiteral */:
+                return true;
+            default:
+                return false;
+        }
+    }
+    ts.isStringTextContainingNode = isStringTextContainingNode;
+    // Identifiers
+    /* @internal */
+    function isGeneratedIdentifier(node) {
+        // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
+        return ts.isIdentifier(node) && node.autoGenerateKind > 0 /* None */;
+    }
+    ts.isGeneratedIdentifier = isGeneratedIdentifier;
+    // Keywords
+    /* @internal */
+    function isModifierKind(token) {
+        switch (token) {
+            case 117 /* AbstractKeyword */:
+            case 120 /* AsyncKeyword */:
+            case 76 /* ConstKeyword */:
+            case 124 /* DeclareKeyword */:
+            case 79 /* DefaultKeyword */:
+            case 84 /* ExportKeyword */:
+            case 114 /* PublicKeyword */:
+            case 112 /* PrivateKeyword */:
+            case 113 /* ProtectedKeyword */:
+            case 131 /* ReadonlyKeyword */:
+            case 115 /* StaticKeyword */:
+                return true;
+        }
+        return false;
+    }
+    ts.isModifierKind = isModifierKind;
+    function isModifier(node) {
+        return isModifierKind(node.kind);
+    }
+    ts.isModifier = isModifier;
+    function isEntityName(node) {
+        var kind = node.kind;
+        return kind === 143 /* QualifiedName */
+            || kind === 71 /* Identifier */;
+    }
+    ts.isEntityName = isEntityName;
+    function isPropertyName(node) {
+        var kind = node.kind;
+        return kind === 71 /* Identifier */
+            || kind === 9 /* StringLiteral */
+            || kind === 8 /* NumericLiteral */
+            || kind === 144 /* ComputedPropertyName */;
+    }
+    ts.isPropertyName = isPropertyName;
+    function isBindingName(node) {
+        var kind = node.kind;
+        return kind === 71 /* Identifier */
+            || kind === 174 /* ObjectBindingPattern */
+            || kind === 175 /* ArrayBindingPattern */;
+    }
+    ts.isBindingName = isBindingName;
+    // Functions
+    function isFunctionLike(node) {
+        return node && isFunctionLikeKind(node.kind);
+    }
+    ts.isFunctionLike = isFunctionLike;
+    /* @internal */
+    function isFunctionLikeDeclaration(node) {
+        return node && isFunctionLikeDeclarationKind(node.kind);
+    }
+    ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration;
+    function isFunctionLikeDeclarationKind(kind) {
+        switch (kind) {
+            case 228 /* FunctionDeclaration */:
+            case 151 /* MethodDeclaration */:
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+                return true;
+            default:
+                return false;
+        }
+    }
+    /* @internal */
+    function isFunctionLikeKind(kind) {
+        switch (kind) {
+            case 150 /* MethodSignature */:
+            case 155 /* CallSignature */:
+            case 156 /* ConstructSignature */:
+            case 157 /* IndexSignature */:
+            case 160 /* FunctionType */:
+            case 273 /* JSDocFunctionType */:
+            case 161 /* ConstructorType */:
+                return true;
+            default:
+                return isFunctionLikeDeclarationKind(kind);
+        }
+    }
+    ts.isFunctionLikeKind = isFunctionLikeKind;
+    /* @internal */
+    function isFunctionOrModuleBlock(node) {
+        return ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isBlock(node) && isFunctionLike(node.parent);
+    }
+    ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock;
+    // Classes
+    function isClassElement(node) {
+        var kind = node.kind;
+        return kind === 152 /* Constructor */
+            || kind === 149 /* PropertyDeclaration */
+            || kind === 151 /* MethodDeclaration */
+            || kind === 153 /* GetAccessor */
+            || kind === 154 /* SetAccessor */
+            || kind === 157 /* IndexSignature */
+            || kind === 206 /* SemicolonClassElement */
+            || kind === 247 /* MissingDeclaration */;
+    }
+    ts.isClassElement = isClassElement;
+    function isClassLike(node) {
+        return node && (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */);
+    }
+    ts.isClassLike = isClassLike;
+    function isAccessor(node) {
+        return node && (node.kind === 153 /* GetAccessor */ || node.kind === 154 /* SetAccessor */);
+    }
+    ts.isAccessor = isAccessor;
+    // Type members
+    function isTypeElement(node) {
+        var kind = node.kind;
+        return kind === 156 /* ConstructSignature */
+            || kind === 155 /* CallSignature */
+            || kind === 148 /* PropertySignature */
+            || kind === 150 /* MethodSignature */
+            || kind === 157 /* IndexSignature */
+            || kind === 247 /* MissingDeclaration */;
+    }
+    ts.isTypeElement = isTypeElement;
+    function isObjectLiteralElementLike(node) {
+        var kind = node.kind;
+        return kind === 261 /* PropertyAssignment */
+            || kind === 262 /* ShorthandPropertyAssignment */
+            || kind === 263 /* SpreadAssignment */
+            || kind === 151 /* MethodDeclaration */
+            || kind === 153 /* GetAccessor */
+            || kind === 154 /* SetAccessor */
+            || kind === 247 /* MissingDeclaration */;
+    }
+    ts.isObjectLiteralElementLike = isObjectLiteralElementLike;
+    // Type
+    function isTypeNodeKind(kind) {
+        return (kind >= 158 /* FirstTypeNode */ && kind <= 173 /* LastTypeNode */)
+            || kind === 119 /* AnyKeyword */
+            || kind === 133 /* NumberKeyword */
+            || kind === 134 /* ObjectKeyword */
+            || kind === 122 /* BooleanKeyword */
+            || kind === 136 /* StringKeyword */
+            || kind === 137 /* SymbolKeyword */
+            || kind === 99 /* ThisKeyword */
+            || kind === 105 /* VoidKeyword */
+            || kind === 139 /* UndefinedKeyword */
+            || kind === 95 /* NullKeyword */
+            || kind === 130 /* NeverKeyword */
+            || kind === 201 /* ExpressionWithTypeArguments */
+            || kind === 268 /* JSDocAllType */
+            || kind === 269 /* JSDocUnknownType */
+            || kind === 270 /* JSDocNullableType */
+            || kind === 271 /* JSDocNonNullableType */
+            || kind === 272 /* JSDocOptionalType */
+            || kind === 273 /* JSDocFunctionType */
+            || kind === 274 /* JSDocVariadicType */;
+    }
+    /**
+     * Node test that determines whether a node is a valid type node.
+     * This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
+     * of a TypeNode.
+     */
+    function isTypeNode(node) {
+        return isTypeNodeKind(node.kind);
+    }
+    ts.isTypeNode = isTypeNode;
+    function isFunctionOrConstructorTypeNode(node) {
+        switch (node.kind) {
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+                return true;
+        }
+        return false;
+    }
+    ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode;
+    // Binding patterns
+    /* @internal */
+    function isBindingPattern(node) {
+        if (node) {
+            var kind = node.kind;
+            return kind === 175 /* ArrayBindingPattern */
+                || kind === 174 /* ObjectBindingPattern */;
+        }
+        return false;
+    }
+    ts.isBindingPattern = isBindingPattern;
+    /* @internal */
+    function isAssignmentPattern(node) {
+        var kind = node.kind;
+        return kind === 177 /* ArrayLiteralExpression */
+            || kind === 178 /* ObjectLiteralExpression */;
+    }
+    ts.isAssignmentPattern = isAssignmentPattern;
+    /* @internal */
+    function isArrayBindingElement(node) {
+        var kind = node.kind;
+        return kind === 176 /* BindingElement */
+            || kind === 200 /* OmittedExpression */;
+    }
+    ts.isArrayBindingElement = isArrayBindingElement;
+    /**
+     * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
+     */
+    /* @internal */
+    function isDeclarationBindingElement(bindingElement) {
+        switch (bindingElement.kind) {
+            case 226 /* VariableDeclaration */:
+            case 146 /* Parameter */:
+            case 176 /* BindingElement */:
+                return true;
+        }
+        return false;
+    }
+    ts.isDeclarationBindingElement = isDeclarationBindingElement;
+    /**
+     * Determines whether a node is a BindingOrAssignmentPattern
+     */
+    /* @internal */
+    function isBindingOrAssignmentPattern(node) {
+        return isObjectBindingOrAssignmentPattern(node)
+            || isArrayBindingOrAssignmentPattern(node);
+    }
+    ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern;
+    /**
+     * Determines whether a node is an ObjectBindingOrAssignmentPattern
+     */
+    /* @internal */
+    function isObjectBindingOrAssignmentPattern(node) {
+        switch (node.kind) {
+            case 174 /* ObjectBindingPattern */:
+            case 178 /* ObjectLiteralExpression */:
+                return true;
+        }
+        return false;
+    }
+    ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern;
+    /**
+     * Determines whether a node is an ArrayBindingOrAssignmentPattern
+     */
+    /* @internal */
+    function isArrayBindingOrAssignmentPattern(node) {
+        switch (node.kind) {
+            case 175 /* ArrayBindingPattern */:
+            case 177 /* ArrayLiteralExpression */:
+                return true;
+        }
+        return false;
+    }
+    ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern;
+    // Expression
+    function isPropertyAccessOrQualifiedName(node) {
+        var kind = node.kind;
+        return kind === 179 /* PropertyAccessExpression */
+            || kind === 143 /* QualifiedName */;
+    }
+    ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName;
+    function isCallLikeExpression(node) {
+        switch (node.kind) {
+            case 251 /* JsxOpeningElement */:
+            case 250 /* JsxSelfClosingElement */:
+            case 181 /* CallExpression */:
+            case 182 /* NewExpression */:
+            case 183 /* TaggedTemplateExpression */:
+            case 147 /* Decorator */:
+                return true;
+            default:
+                return false;
+        }
+    }
+    ts.isCallLikeExpression = isCallLikeExpression;
+    function isCallOrNewExpression(node) {
+        return node.kind === 181 /* CallExpression */ || node.kind === 182 /* NewExpression */;
+    }
+    ts.isCallOrNewExpression = isCallOrNewExpression;
+    function isTemplateLiteral(node) {
+        var kind = node.kind;
+        return kind === 196 /* TemplateExpression */
+            || kind === 13 /* NoSubstitutionTemplateLiteral */;
+    }
+    ts.isTemplateLiteral = isTemplateLiteral;
+    /* @internal */
+    function isLeftHandSideExpression(node) {
+        return isLeftHandSideExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
+    }
+    ts.isLeftHandSideExpression = isLeftHandSideExpression;
+    function isLeftHandSideExpressionKind(kind) {
+        switch (kind) {
+            case 179 /* PropertyAccessExpression */:
+            case 180 /* ElementAccessExpression */:
+            case 182 /* NewExpression */:
+            case 181 /* CallExpression */:
+            case 249 /* JsxElement */:
+            case 250 /* JsxSelfClosingElement */:
+            case 183 /* TaggedTemplateExpression */:
+            case 177 /* ArrayLiteralExpression */:
+            case 185 /* ParenthesizedExpression */:
+            case 178 /* ObjectLiteralExpression */:
+            case 199 /* ClassExpression */:
+            case 186 /* FunctionExpression */:
+            case 71 /* Identifier */:
+            case 12 /* RegularExpressionLiteral */:
+            case 8 /* NumericLiteral */:
+            case 9 /* StringLiteral */:
+            case 13 /* NoSubstitutionTemplateLiteral */:
+            case 196 /* TemplateExpression */:
+            case 86 /* FalseKeyword */:
+            case 95 /* NullKeyword */:
+            case 99 /* ThisKeyword */:
+            case 101 /* TrueKeyword */:
+            case 97 /* SuperKeyword */:
+            case 203 /* NonNullExpression */:
+            case 204 /* MetaProperty */:
+            case 91 /* ImportKeyword */:// technically this is only an Expression if it's in a CallExpression
+                return true;
+            default:
+                return false;
+        }
+    }
+    /* @internal */
+    function isUnaryExpression(node) {
+        return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
+    }
+    ts.isUnaryExpression = isUnaryExpression;
+    function isUnaryExpressionKind(kind) {
+        switch (kind) {
+            case 192 /* PrefixUnaryExpression */:
+            case 193 /* PostfixUnaryExpression */:
+            case 188 /* DeleteExpression */:
+            case 189 /* TypeOfExpression */:
+            case 190 /* VoidExpression */:
+            case 191 /* AwaitExpression */:
+            case 184 /* TypeAssertionExpression */:
+                return true;
+            default:
+                return isLeftHandSideExpressionKind(kind);
+        }
+    }
+    /* @internal */
+    function isUnaryExpressionWithWrite(expr) {
+        switch (expr.kind) {
+            case 193 /* PostfixUnaryExpression */:
+                return true;
+            case 192 /* PrefixUnaryExpression */:
+                return expr.operator === 43 /* PlusPlusToken */ ||
+                    expr.operator === 44 /* MinusMinusToken */;
+            default:
+                return false;
+        }
+    }
+    ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite;
+    /* @internal */
+    /**
+     * Determines whether a node is an expression based only on its kind.
+     * Use `isPartOfExpression` if not in transforms.
+     */
+    function isExpression(node) {
+        return isExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
+    }
+    ts.isExpression = isExpression;
+    function isExpressionKind(kind) {
+        switch (kind) {
+            case 195 /* ConditionalExpression */:
+            case 197 /* YieldExpression */:
+            case 187 /* ArrowFunction */:
+            case 194 /* BinaryExpression */:
+            case 198 /* SpreadElement */:
+            case 202 /* AsExpression */:
+            case 200 /* OmittedExpression */:
+            case 289 /* CommaListExpression */:
+            case 288 /* PartiallyEmittedExpression */:
+                return true;
+            default:
+                return isUnaryExpressionKind(kind);
+        }
+    }
+    function isAssertionExpression(node) {
+        var kind = node.kind;
+        return kind === 184 /* TypeAssertionExpression */
+            || kind === 202 /* AsExpression */;
+    }
+    ts.isAssertionExpression = isAssertionExpression;
+    /* @internal */
+    function isPartiallyEmittedExpression(node) {
+        return node.kind === 288 /* PartiallyEmittedExpression */;
+    }
+    ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression;
+    /* @internal */
+    function isNotEmittedStatement(node) {
+        return node.kind === 287 /* NotEmittedStatement */;
+    }
+    ts.isNotEmittedStatement = isNotEmittedStatement;
+    /* @internal */
+    function isNotEmittedOrPartiallyEmittedNode(node) {
+        return isNotEmittedStatement(node)
+            || isPartiallyEmittedExpression(node);
+    }
+    ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode;
+    // Statement
+    function isIterationStatement(node, lookInLabeledStatements) {
+        switch (node.kind) {
+            case 214 /* ForStatement */:
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+            case 212 /* DoStatement */:
+            case 213 /* WhileStatement */:
+                return true;
+            case 222 /* LabeledStatement */:
+                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
+        }
+        return false;
+    }
+    ts.isIterationStatement = isIterationStatement;
+    /* @internal */
+    function isForInOrOfStatement(node) {
+        return node.kind === 215 /* ForInStatement */ || node.kind === 216 /* ForOfStatement */;
+    }
+    ts.isForInOrOfStatement = isForInOrOfStatement;
+    // Element
+    /* @internal */
+    function isConciseBody(node) {
+        return ts.isBlock(node)
+            || isExpression(node);
+    }
+    ts.isConciseBody = isConciseBody;
+    /* @internal */
+    function isFunctionBody(node) {
+        return ts.isBlock(node);
+    }
+    ts.isFunctionBody = isFunctionBody;
+    /* @internal */
+    function isForInitializer(node) {
+        return ts.isVariableDeclarationList(node)
+            || isExpression(node);
+    }
+    ts.isForInitializer = isForInitializer;
+    /* @internal */
+    function isModuleBody(node) {
+        var kind = node.kind;
+        return kind === 234 /* ModuleBlock */
+            || kind === 233 /* ModuleDeclaration */
+            || kind === 71 /* Identifier */;
+    }
+    ts.isModuleBody = isModuleBody;
+    /* @internal */
+    function isNamespaceBody(node) {
+        var kind = node.kind;
+        return kind === 234 /* ModuleBlock */
+            || kind === 233 /* ModuleDeclaration */;
+    }
+    ts.isNamespaceBody = isNamespaceBody;
+    /* @internal */
+    function isJSDocNamespaceBody(node) {
+        var kind = node.kind;
+        return kind === 71 /* Identifier */
+            || kind === 233 /* ModuleDeclaration */;
+    }
+    ts.isJSDocNamespaceBody = isJSDocNamespaceBody;
+    /* @internal */
+    function isNamedImportBindings(node) {
+        var kind = node.kind;
+        return kind === 241 /* NamedImports */
+            || kind === 240 /* NamespaceImport */;
+    }
+    ts.isNamedImportBindings = isNamedImportBindings;
+    /* @internal */
+    function isModuleOrEnumDeclaration(node) {
+        return node.kind === 233 /* ModuleDeclaration */ || node.kind === 232 /* EnumDeclaration */;
+    }
+    ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration;
+    function isDeclarationKind(kind) {
+        return kind === 187 /* ArrowFunction */
+            || kind === 176 /* BindingElement */
+            || kind === 229 /* ClassDeclaration */
+            || kind === 199 /* ClassExpression */
+            || kind === 152 /* Constructor */
+            || kind === 232 /* EnumDeclaration */
+            || kind === 264 /* EnumMember */
+            || kind === 246 /* ExportSpecifier */
+            || kind === 228 /* FunctionDeclaration */
+            || kind === 186 /* FunctionExpression */
+            || kind === 153 /* GetAccessor */
+            || kind === 239 /* ImportClause */
+            || kind === 237 /* ImportEqualsDeclaration */
+            || kind === 242 /* ImportSpecifier */
+            || kind === 230 /* InterfaceDeclaration */
+            || kind === 253 /* JsxAttribute */
+            || kind === 151 /* MethodDeclaration */
+            || kind === 150 /* MethodSignature */
+            || kind === 233 /* ModuleDeclaration */
+            || kind === 236 /* NamespaceExportDeclaration */
+            || kind === 240 /* NamespaceImport */
+            || kind === 146 /* Parameter */
+            || kind === 261 /* PropertyAssignment */
+            || kind === 149 /* PropertyDeclaration */
+            || kind === 148 /* PropertySignature */
+            || kind === 154 /* SetAccessor */
+            || kind === 262 /* ShorthandPropertyAssignment */
+            || kind === 231 /* TypeAliasDeclaration */
+            || kind === 145 /* TypeParameter */
+            || kind === 226 /* VariableDeclaration */
+            || kind === 283 /* JSDocTypedefTag */;
+    }
+    function isDeclarationStatementKind(kind) {
+        return kind === 228 /* FunctionDeclaration */
+            || kind === 247 /* MissingDeclaration */
+            || kind === 229 /* ClassDeclaration */
+            || kind === 230 /* InterfaceDeclaration */
+            || kind === 231 /* TypeAliasDeclaration */
+            || kind === 232 /* EnumDeclaration */
+            || kind === 233 /* ModuleDeclaration */
+            || kind === 238 /* ImportDeclaration */
+            || kind === 237 /* ImportEqualsDeclaration */
+            || kind === 244 /* ExportDeclaration */
+            || kind === 243 /* ExportAssignment */
+            || kind === 236 /* NamespaceExportDeclaration */;
+    }
+    function isStatementKindButNotDeclarationKind(kind) {
+        return kind === 218 /* BreakStatement */
+            || kind === 217 /* ContinueStatement */
+            || kind === 225 /* DebuggerStatement */
+            || kind === 212 /* DoStatement */
+            || kind === 210 /* ExpressionStatement */
+            || kind === 209 /* EmptyStatement */
+            || kind === 215 /* ForInStatement */
+            || kind === 216 /* ForOfStatement */
+            || kind === 214 /* ForStatement */
+            || kind === 211 /* IfStatement */
+            || kind === 222 /* LabeledStatement */
+            || kind === 219 /* ReturnStatement */
+            || kind === 221 /* SwitchStatement */
+            || kind === 223 /* ThrowStatement */
+            || kind === 224 /* TryStatement */
+            || kind === 208 /* VariableStatement */
+            || kind === 213 /* WhileStatement */
+            || kind === 220 /* WithStatement */
+            || kind === 287 /* NotEmittedStatement */
+            || kind === 291 /* EndOfDeclarationMarker */
+            || kind === 290 /* MergeDeclarationMarker */;
+    }
+    /* @internal */
+    function isDeclaration(node) {
+        if (node.kind === 145 /* TypeParameter */) {
+            return node.parent.kind !== 282 /* JSDocTemplateTag */ || ts.isInJavaScriptFile(node);
+        }
+        return isDeclarationKind(node.kind);
+    }
+    ts.isDeclaration = isDeclaration;
+    /* @internal */
+    function isDeclarationStatement(node) {
+        return isDeclarationStatementKind(node.kind);
+    }
+    ts.isDeclarationStatement = isDeclarationStatement;
+    /**
+     * Determines whether the node is a statement that is not also a declaration
+     */
+    /* @internal */
+    function isStatementButNotDeclaration(node) {
+        return isStatementKindButNotDeclarationKind(node.kind);
+    }
+    ts.isStatementButNotDeclaration = isStatementButNotDeclaration;
+    /* @internal */
+    function isStatement(node) {
+        var kind = node.kind;
+        return isStatementKindButNotDeclarationKind(kind)
+            || isDeclarationStatementKind(kind)
+            || isBlockStatement(node);
+    }
+    ts.isStatement = isStatement;
+    function isBlockStatement(node) {
+        if (node.kind !== 207 /* Block */)
+            return false;
+        if (node.parent !== undefined) {
+            if (node.parent.kind === 224 /* TryStatement */ || node.parent.kind === 260 /* CatchClause */) {
+                return false;
+            }
+        }
+        return !ts.isFunctionBlock(node);
+    }
+    // Module references
+    /* @internal */
+    function isModuleReference(node) {
+        var kind = node.kind;
+        return kind === 248 /* ExternalModuleReference */
+            || kind === 143 /* QualifiedName */
+            || kind === 71 /* Identifier */;
+    }
+    ts.isModuleReference = isModuleReference;
+    // JSX
+    /* @internal */
+    function isJsxTagNameExpression(node) {
+        var kind = node.kind;
+        return kind === 99 /* ThisKeyword */
+            || kind === 71 /* Identifier */
+            || kind === 179 /* PropertyAccessExpression */;
+    }
+    ts.isJsxTagNameExpression = isJsxTagNameExpression;
+    /* @internal */
+    function isJsxChild(node) {
+        var kind = node.kind;
+        return kind === 249 /* JsxElement */
+            || kind === 256 /* JsxExpression */
+            || kind === 250 /* JsxSelfClosingElement */
+            || kind === 10 /* JsxText */;
+    }
+    ts.isJsxChild = isJsxChild;
+    /* @internal */
+    function isJsxAttributeLike(node) {
+        var kind = node.kind;
+        return kind === 253 /* JsxAttribute */
+            || kind === 255 /* JsxSpreadAttribute */;
+    }
+    ts.isJsxAttributeLike = isJsxAttributeLike;
+    /* @internal */
+    function isStringLiteralOrJsxExpression(node) {
+        var kind = node.kind;
+        return kind === 9 /* StringLiteral */
+            || kind === 256 /* JsxExpression */;
+    }
+    ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression;
+    function isJsxOpeningLikeElement(node) {
+        var kind = node.kind;
+        return kind === 251 /* JsxOpeningElement */
+            || kind === 250 /* JsxSelfClosingElement */;
+    }
+    ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement;
+    // Clauses
+    function isCaseOrDefaultClause(node) {
+        var kind = node.kind;
+        return kind === 257 /* CaseClause */
+            || kind === 258 /* DefaultClause */;
+    }
+    ts.isCaseOrDefaultClause = isCaseOrDefaultClause;
+    // JSDoc
+    /** True if node is of some JSDoc syntax kind. */
+    /* @internal */
+    function isJSDocNode(node) {
+        return node.kind >= 267 /* FirstJSDocNode */ && node.kind <= 285 /* LastJSDocNode */;
+    }
+    ts.isJSDocNode = isJSDocNode;
+    /** True if node is of a kind that may contain comment text. */
+    function isJSDocCommentContainingNode(node) {
+        return node.kind === 275 /* JSDocComment */ || isJSDocTag(node);
+    }
+    ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode;
+    // TODO: determine what this does before making it public.
+    /* @internal */
+    function isJSDocTag(node) {
+        return node.kind >= 276 /* FirstJSDocTagNode */ && node.kind <= 285 /* LastJSDocTagNode */;
+    }
+    ts.isJSDocTag = isJSDocTag;
+    function isSetAccessor(node) {
+        return node.kind === 154 /* SetAccessor */;
+    }
+    ts.isSetAccessor = isSetAccessor;
+    function isGetAccessor(node) {
+        return node.kind === 153 /* GetAccessor */;
+    }
+    ts.isGetAccessor = isGetAccessor;
+    /** True if has jsdoc nodes attached to it. */
+    /* @internal */
+    function hasJSDocNodes(node) {
+        return !!node.jsDoc && node.jsDoc.length > 0;
+    }
+    ts.hasJSDocNodes = hasJSDocNodes;
+})(ts || (ts = {}));
+/// <reference path="utilities.ts"/>
+/// <reference path="scanner.ts"/>
+var ts;
+(function (ts) {
+    var SignatureFlags;
+    (function (SignatureFlags) {
+        SignatureFlags[SignatureFlags["None"] = 0] = "None";
+        SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield";
+        SignatureFlags[SignatureFlags["Await"] = 2] = "Await";
+        SignatureFlags[SignatureFlags["Type"] = 4] = "Type";
+        SignatureFlags[SignatureFlags["RequireCompleteParameterList"] = 8] = "RequireCompleteParameterList";
+        SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace";
+        SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc";
+    })(SignatureFlags || (SignatureFlags = {}));
+    var NodeConstructor;
+    var TokenConstructor;
+    var IdentifierConstructor;
+    var SourceFileConstructor;
+    function createNode(kind, pos, end) {
+        if (kind === 265 /* SourceFile */) {
+            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
+        }
+        else if (kind === 71 /* Identifier */) {
+            return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end);
+        }
+        else if (!ts.isNodeKind(kind)) {
+            return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end);
+        }
+        else {
+            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
+        }
+    }
+    ts.createNode = createNode;
+    function visitNode(cbNode, node) {
+        return node && cbNode(node);
+    }
+    function visitNodes(cbNode, cbNodes, nodes) {
+        if (nodes) {
+            if (cbNodes) {
+                return cbNodes(nodes);
+            }
+            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                var node = nodes_1[_i];
+                var result = cbNode(node);
+                if (result) {
+                    return result;
+                }
+            }
+        }
+    }
+    /**
+     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
+     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
+     * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
+     * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
+     *
+     * @param node a given node to visit its children
+     * @param cbNode a callback to be invoked for all child nodes
+     * @param cbNodes a callback to be invoked for embedded array
+     *
+     * @remarks `forEachChild` must visit the children of a node in the order
+     * that they appear in the source code. The language service depends on this property to locate nodes by position.
+     */
+    function forEachChild(node, cbNode, cbNodes) {
+        if (!node || node.kind <= 142 /* LastToken */) {
+            return;
+        }
+        switch (node.kind) {
+            case 143 /* QualifiedName */:
+                return visitNode(cbNode, node.left) ||
+                    visitNode(cbNode, node.right);
+            case 145 /* TypeParameter */:
+                return visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.constraint) ||
+                    visitNode(cbNode, node.default) ||
+                    visitNode(cbNode, node.expression);
+            case 262 /* ShorthandPropertyAssignment */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.questionToken) ||
+                    visitNode(cbNode, node.equalsToken) ||
+                    visitNode(cbNode, node.objectAssignmentInitializer);
+            case 263 /* SpreadAssignment */:
+                return visitNode(cbNode, node.expression);
+            case 146 /* Parameter */:
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+            case 261 /* PropertyAssignment */:
+            case 226 /* VariableDeclaration */:
+            case 176 /* BindingElement */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.propertyName) ||
+                    visitNode(cbNode, node.dotDotDotToken) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.questionToken) ||
+                    visitNode(cbNode, node.type) ||
+                    visitNode(cbNode, node.initializer);
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+            case 155 /* CallSignature */:
+            case 156 /* ConstructSignature */:
+            case 157 /* IndexSignature */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
+                    visitNodes(cbNode, cbNodes, node.parameters) ||
+                    visitNode(cbNode, node.type);
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 186 /* FunctionExpression */:
+            case 228 /* FunctionDeclaration */:
+            case 187 /* ArrowFunction */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.asteriskToken) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.questionToken) ||
+                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
+                    visitNodes(cbNode, cbNodes, node.parameters) ||
+                    visitNode(cbNode, node.type) ||
+                    visitNode(cbNode, node.equalsGreaterThanToken) ||
+                    visitNode(cbNode, node.body);
+            case 159 /* TypeReference */:
+                return visitNode(cbNode, node.typeName) ||
+                    visitNodes(cbNode, cbNodes, node.typeArguments);
+            case 158 /* TypePredicate */:
+                return visitNode(cbNode, node.parameterName) ||
+                    visitNode(cbNode, node.type);
+            case 162 /* TypeQuery */:
+                return visitNode(cbNode, node.exprName);
+            case 163 /* TypeLiteral */:
+                return visitNodes(cbNode, cbNodes, node.members);
+            case 164 /* ArrayType */:
+                return visitNode(cbNode, node.elementType);
+            case 165 /* TupleType */:
+                return visitNodes(cbNode, cbNodes, node.elementTypes);
+            case 166 /* UnionType */:
+            case 167 /* IntersectionType */:
+                return visitNodes(cbNode, cbNodes, node.types);
+            case 168 /* ParenthesizedType */:
+            case 170 /* TypeOperator */:
+                return visitNode(cbNode, node.type);
+            case 171 /* IndexedAccessType */:
+                return visitNode(cbNode, node.objectType) ||
+                    visitNode(cbNode, node.indexType);
+            case 172 /* MappedType */:
+                return visitNode(cbNode, node.readonlyToken) ||
+                    visitNode(cbNode, node.typeParameter) ||
+                    visitNode(cbNode, node.questionToken) ||
+                    visitNode(cbNode, node.type);
+            case 173 /* LiteralType */:
+                return visitNode(cbNode, node.literal);
+            case 174 /* ObjectBindingPattern */:
+            case 175 /* ArrayBindingPattern */:
+                return visitNodes(cbNode, cbNodes, node.elements);
+            case 177 /* ArrayLiteralExpression */:
+                return visitNodes(cbNode, cbNodes, node.elements);
+            case 178 /* ObjectLiteralExpression */:
+                return visitNodes(cbNode, cbNodes, node.properties);
+            case 179 /* PropertyAccessExpression */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.name);
+            case 180 /* ElementAccessExpression */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.argumentExpression);
+            case 181 /* CallExpression */:
+            case 182 /* NewExpression */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
+                    visitNodes(cbNode, cbNodes, node.arguments);
+            case 183 /* TaggedTemplateExpression */:
+                return visitNode(cbNode, node.tag) ||
+                    visitNode(cbNode, node.template);
+            case 184 /* TypeAssertionExpression */:
+                return visitNode(cbNode, node.type) ||
+                    visitNode(cbNode, node.expression);
+            case 185 /* ParenthesizedExpression */:
+                return visitNode(cbNode, node.expression);
+            case 188 /* DeleteExpression */:
+                return visitNode(cbNode, node.expression);
+            case 189 /* TypeOfExpression */:
+                return visitNode(cbNode, node.expression);
+            case 190 /* VoidExpression */:
+                return visitNode(cbNode, node.expression);
+            case 192 /* PrefixUnaryExpression */:
+                return visitNode(cbNode, node.operand);
+            case 197 /* YieldExpression */:
+                return visitNode(cbNode, node.asteriskToken) ||
+                    visitNode(cbNode, node.expression);
+            case 191 /* AwaitExpression */:
+                return visitNode(cbNode, node.expression);
+            case 193 /* PostfixUnaryExpression */:
+                return visitNode(cbNode, node.operand);
+            case 194 /* BinaryExpression */:
+                return visitNode(cbNode, node.left) ||
+                    visitNode(cbNode, node.operatorToken) ||
+                    visitNode(cbNode, node.right);
+            case 202 /* AsExpression */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.type);
+            case 203 /* NonNullExpression */:
+                return visitNode(cbNode, node.expression);
+            case 204 /* MetaProperty */:
+                return visitNode(cbNode, node.name);
+            case 195 /* ConditionalExpression */:
+                return visitNode(cbNode, node.condition) ||
+                    visitNode(cbNode, node.questionToken) ||
+                    visitNode(cbNode, node.whenTrue) ||
+                    visitNode(cbNode, node.colonToken) ||
+                    visitNode(cbNode, node.whenFalse);
+            case 198 /* SpreadElement */:
+                return visitNode(cbNode, node.expression);
+            case 207 /* Block */:
+            case 234 /* ModuleBlock */:
+                return visitNodes(cbNode, cbNodes, node.statements);
+            case 265 /* SourceFile */:
+                return visitNodes(cbNode, cbNodes, node.statements) ||
+                    visitNode(cbNode, node.endOfFileToken);
+            case 208 /* VariableStatement */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.declarationList);
+            case 227 /* VariableDeclarationList */:
+                return visitNodes(cbNode, cbNodes, node.declarations);
+            case 210 /* ExpressionStatement */:
+                return visitNode(cbNode, node.expression);
+            case 211 /* IfStatement */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.thenStatement) ||
+                    visitNode(cbNode, node.elseStatement);
+            case 212 /* DoStatement */:
+                return visitNode(cbNode, node.statement) ||
+                    visitNode(cbNode, node.expression);
+            case 213 /* WhileStatement */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.statement);
+            case 214 /* ForStatement */:
+                return visitNode(cbNode, node.initializer) ||
+                    visitNode(cbNode, node.condition) ||
+                    visitNode(cbNode, node.incrementor) ||
+                    visitNode(cbNode, node.statement);
+            case 215 /* ForInStatement */:
+                return visitNode(cbNode, node.initializer) ||
+                    visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.statement);
+            case 216 /* ForOfStatement */:
+                return visitNode(cbNode, node.awaitModifier) ||
+                    visitNode(cbNode, node.initializer) ||
+                    visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.statement);
+            case 217 /* ContinueStatement */:
+            case 218 /* BreakStatement */:
+                return visitNode(cbNode, node.label);
+            case 219 /* ReturnStatement */:
+                return visitNode(cbNode, node.expression);
+            case 220 /* WithStatement */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.statement);
+            case 221 /* SwitchStatement */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNode(cbNode, node.caseBlock);
+            case 235 /* CaseBlock */:
+                return visitNodes(cbNode, cbNodes, node.clauses);
+            case 257 /* CaseClause */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNodes(cbNode, cbNodes, node.statements);
+            case 258 /* DefaultClause */:
+                return visitNodes(cbNode, cbNodes, node.statements);
+            case 222 /* LabeledStatement */:
+                return visitNode(cbNode, node.label) ||
+                    visitNode(cbNode, node.statement);
+            case 223 /* ThrowStatement */:
+                return visitNode(cbNode, node.expression);
+            case 224 /* TryStatement */:
+                return visitNode(cbNode, node.tryBlock) ||
+                    visitNode(cbNode, node.catchClause) ||
+                    visitNode(cbNode, node.finallyBlock);
+            case 260 /* CatchClause */:
+                return visitNode(cbNode, node.variableDeclaration) ||
+                    visitNode(cbNode, node.block);
+            case 147 /* Decorator */:
+                return visitNode(cbNode, node.expression);
+            case 229 /* ClassDeclaration */:
+            case 199 /* ClassExpression */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
+                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
+                    visitNodes(cbNode, cbNodes, node.members);
+            case 230 /* InterfaceDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
+                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
+                    visitNodes(cbNode, cbNodes, node.members);
+            case 231 /* TypeAliasDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
+                    visitNode(cbNode, node.type);
+            case 232 /* EnumDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNodes(cbNode, cbNodes, node.members);
+            case 264 /* EnumMember */:
+                return visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.initializer);
+            case 233 /* ModuleDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.body);
+            case 237 /* ImportEqualsDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.moduleReference);
+            case 238 /* ImportDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.importClause) ||
+                    visitNode(cbNode, node.moduleSpecifier);
+            case 239 /* ImportClause */:
+                return visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.namedBindings);
+            case 236 /* NamespaceExportDeclaration */:
+                return visitNode(cbNode, node.name);
+            case 240 /* NamespaceImport */:
+                return visitNode(cbNode, node.name);
+            case 241 /* NamedImports */:
+            case 245 /* NamedExports */:
+                return visitNodes(cbNode, cbNodes, node.elements);
+            case 244 /* ExportDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.exportClause) ||
+                    visitNode(cbNode, node.moduleSpecifier);
+            case 242 /* ImportSpecifier */:
+            case 246 /* ExportSpecifier */:
+                return visitNode(cbNode, node.propertyName) ||
+                    visitNode(cbNode, node.name);
+            case 243 /* ExportAssignment */:
+                return visitNodes(cbNode, cbNodes, node.decorators) ||
+                    visitNodes(cbNode, cbNodes, node.modifiers) ||
+                    visitNode(cbNode, node.expression);
+            case 196 /* TemplateExpression */:
+                return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans);
+            case 205 /* TemplateSpan */:
+                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
+            case 144 /* ComputedPropertyName */:
+                return visitNode(cbNode, node.expression);
+            case 259 /* HeritageClause */:
+                return visitNodes(cbNode, cbNodes, node.types);
+            case 201 /* ExpressionWithTypeArguments */:
+                return visitNode(cbNode, node.expression) ||
+                    visitNodes(cbNode, cbNodes, node.typeArguments);
+            case 248 /* ExternalModuleReference */:
+                return visitNode(cbNode, node.expression);
+            case 247 /* MissingDeclaration */:
+                return visitNodes(cbNode, cbNodes, node.decorators);
+            case 289 /* CommaListExpression */:
+                return visitNodes(cbNode, cbNodes, node.elements);
+            case 249 /* JsxElement */:
+                return visitNode(cbNode, node.openingElement) ||
+                    visitNodes(cbNode, cbNodes, node.children) ||
+                    visitNode(cbNode, node.closingElement);
+            case 250 /* JsxSelfClosingElement */:
+            case 251 /* JsxOpeningElement */:
+                return visitNode(cbNode, node.tagName) ||
+                    visitNode(cbNode, node.attributes);
+            case 254 /* JsxAttributes */:
+                return visitNodes(cbNode, cbNodes, node.properties);
+            case 253 /* JsxAttribute */:
+                return visitNode(cbNode, node.name) ||
+                    visitNode(cbNode, node.initializer);
+            case 255 /* JsxSpreadAttribute */:
+                return visitNode(cbNode, node.expression);
+            case 256 /* JsxExpression */:
+                return visitNode(cbNode, node.dotDotDotToken) ||
+                    visitNode(cbNode, node.expression);
+            case 252 /* JsxClosingElement */:
+                return visitNode(cbNode, node.tagName);
+            case 267 /* JSDocTypeExpression */:
+                return visitNode(cbNode, node.type);
+            case 271 /* JSDocNonNullableType */:
+                return visitNode(cbNode, node.type);
+            case 270 /* JSDocNullableType */:
+                return visitNode(cbNode, node.type);
+            case 272 /* JSDocOptionalType */:
+                return visitNode(cbNode, node.type);
+            case 273 /* JSDocFunctionType */:
+                return visitNodes(cbNode, cbNodes, node.parameters) ||
+                    visitNode(cbNode, node.type);
+            case 274 /* JSDocVariadicType */:
+                return visitNode(cbNode, node.type);
+            case 275 /* JSDocComment */:
+                return visitNodes(cbNode, cbNodes, node.tags);
+            case 279 /* JSDocParameterTag */:
+            case 284 /* JSDocPropertyTag */:
+                if (node.isNameFirst) {
+                    return visitNode(cbNode, node.name) ||
+                        visitNode(cbNode, node.typeExpression);
+                }
+                else {
+                    return visitNode(cbNode, node.typeExpression) ||
+                        visitNode(cbNode, node.name);
+                }
+            case 280 /* JSDocReturnTag */:
+                return visitNode(cbNode, node.typeExpression);
+            case 281 /* JSDocTypeTag */:
+                return visitNode(cbNode, node.typeExpression);
+            case 277 /* JSDocAugmentsTag */:
+                return visitNode(cbNode, node.class);
+            case 282 /* JSDocTemplateTag */:
+                return visitNodes(cbNode, cbNodes, node.typeParameters);
+            case 283 /* JSDocTypedefTag */:
+                if (node.typeExpression &&
+                    node.typeExpression.kind === 267 /* JSDocTypeExpression */) {
+                    return visitNode(cbNode, node.typeExpression) ||
+                        visitNode(cbNode, node.fullName);
+                }
+                else {
+                    return visitNode(cbNode, node.fullName) ||
+                        visitNode(cbNode, node.typeExpression);
+                }
+            case 285 /* JSDocTypeLiteral */:
+                if (node.jsDocPropertyTags) {
+                    for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) {
+                        var tag = _a[_i];
+                        visitNode(cbNode, tag);
+                    }
+                }
+                return;
+            case 288 /* PartiallyEmittedExpression */:
+                return visitNode(cbNode, node.expression);
+        }
+    }
+    ts.forEachChild = forEachChild;
+    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
+        if (setParentNodes === void 0) { setParentNodes = false; }
+        ts.performance.mark("beforeParse");
+        var result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
+        ts.performance.mark("afterParse");
+        ts.performance.measure("Parse", "beforeParse", "afterParse");
+        return result;
+    }
+    ts.createSourceFile = createSourceFile;
+    function parseIsolatedEntityName(text, languageVersion) {
+        return Parser.parseIsolatedEntityName(text, languageVersion);
+    }
+    ts.parseIsolatedEntityName = parseIsolatedEntityName;
+    /**
+     * Parse json text into SyntaxTree and return node and parse errors if any
+     * @param fileName
+     * @param sourceText
+     */
+    function parseJsonText(fileName, sourceText) {
+        return Parser.parseJsonText(fileName, sourceText);
+    }
+    ts.parseJsonText = parseJsonText;
+    // See also `isExternalOrCommonJsModule` in utilities.ts
+    function isExternalModule(file) {
+        return file.externalModuleIndicator !== undefined;
+    }
+    ts.isExternalModule = isExternalModule;
+    // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
+    // indicates what changed between the 'text' that this SourceFile has and the 'newText'.
+    // The SourceFile will be created with the compiler attempting to reuse as many nodes from
+    // this file as possible.
+    //
+    // Note: this function mutates nodes from this SourceFile. That means any existing nodes
+    // from this SourceFile that are being held onto may change as a result (including
+    // becoming detached from any SourceFile).  It is recommended that this SourceFile not
+    // be used once 'update' is called on it.
+    function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
+        var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
+        // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
+        // We will manually port the flag to the new source file.
+        newSourceFile.flags |= (sourceFile.flags & 524288 /* PossiblyContainsDynamicImport */);
+        return newSourceFile;
+    }
+    ts.updateSourceFile = updateSourceFile;
+    /* @internal */
+    function parseIsolatedJSDocComment(content, start, length) {
+        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
+        if (result && result.jsDoc) {
+            // because the jsDocComment was parsed out of the source file, it might
+            // not be covered by the fixupParentReferences.
+            Parser.fixupParentReferences(result.jsDoc);
+        }
+        return result;
+    }
+    ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
+    /* @internal */
+    // Exposed only for testing.
+    function parseJSDocTypeExpressionForTests(content, start, length) {
+        return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length);
+    }
+    ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
+    // Implement the parser as a singleton module.  We do this for perf reasons because creating
+    // parser instances can actually be expensive enough to impact us on projects with many source
+    // files.
+    var Parser;
+    (function (Parser) {
+        // Share a single scanner across all calls to parse a source file.  This helps speed things
+        // up by avoiding the cost of creating/compiling scanners over and over again.
+        var scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ true);
+        var disallowInAndDecoratorContext = 2048 /* DisallowInContext */ | 8192 /* DecoratorContext */;
+        // capture constructors in 'initializeState' to avoid null checks
+        var NodeConstructor;
+        var TokenConstructor;
+        var IdentifierConstructor;
+        var SourceFileConstructor;
+        var sourceFile;
+        var parseDiagnostics;
+        var syntaxCursor;
+        var currentToken;
+        var sourceText;
+        var nodeCount;
+        var identifiers;
+        var identifierCount;
+        var parsingContext;
+        // Flags that dictate what parsing context we're in.  For example:
+        // Whether or not we are in strict parsing mode.  All that changes in strict parsing mode is
+        // that some tokens that would be considered identifiers may be considered keywords.
+        //
+        // When adding more parser context flags, consider which is the more common case that the
+        // flag will be in.  This should be the 'false' state for that flag.  The reason for this is
+        // that we don't store data in our nodes unless the value is in the *non-default* state.  So,
+        // for example, more often than code 'allows-in' (or doesn't 'disallow-in').  We opt for
+        // 'disallow-in' set to 'false'.  Otherwise, if we had 'allowsIn' set to 'true', then almost
+        // all nodes would need extra state on them to store this info.
+        //
+        // Note:  'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
+        // grammar specification.
+        //
+        // An important thing about these context concepts.  By default they are effectively inherited
+        // while parsing through every grammar production.  i.e. if you don't change them, then when
+        // you parse a sub-production, it will have the same context values as the parent production.
+        // This is great most of the time.  After all, consider all the 'expression' grammar productions
+        // and how nearly all of them pass along the 'in' and 'yield' context values:
+        //
+        // EqualityExpression[In, Yield] :
+        //      RelationalExpression[?In, ?Yield]
+        //      EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
+        //      EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
+        //      EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
+        //      EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
+        //
+        // Where you have to be careful is then understanding what the points are in the grammar
+        // where the values are *not* passed along.  For example:
+        //
+        // SingleNameBinding[Yield,GeneratorParameter]
+        //      [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
+        //      [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
+        //
+        // Here this is saying that if the GeneratorParameter context flag is set, that we should
+        // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
+        // and we should explicitly unset the 'yield' context flag before calling into the Initializer.
+        // production.  Conversely, if the GeneratorParameter context flag is not set, then we
+        // should leave the 'yield' context flag alone.
+        //
+        // Getting this all correct is tricky and requires careful reading of the grammar to
+        // understand when these values should be changed versus when they should be inherited.
+        //
+        // Note: it should not be necessary to save/restore these flags during speculative/lookahead
+        // parsing.  These context flags are naturally stored and restored through normal recursive
+        // descent parsing and unwinding.
+        var contextFlags;
+        // Whether or not we've had a parse error since creating the last AST node.  If we have
+        // encountered an error, it will be stored on the next AST node we create.  Parse errors
+        // can be broken down into three categories:
+        //
+        // 1) An error that occurred during scanning.  For example, an unterminated literal, or a
+        //    character that was completely not understood.
+        //
+        // 2) A token was expected, but was not present.  This type of error is commonly produced
+        //    by the 'parseExpected' function.
+        //
+        // 3) A token was present that no parsing function was able to consume.  This type of error
+        //    only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser
+        //    decides to skip the token.
+        //
+        // In all of these cases, we want to mark the next node as having had an error before it.
+        // With this mark, we can know in incremental settings if this node can be reused, or if
+        // we have to reparse it.  If we don't keep this information around, we may just reuse the
+        // node.  in that event we would then not produce the same errors as we did before, causing
+        // significant confusion problems.
+        //
+        // Note: it is necessary that this value be saved/restored during speculative/lookahead
+        // parsing.  During lookahead parsing, we will often create a node.  That node will have
+        // this value attached, and then this value will be set back to 'false'.  If we decide to
+        // rewind, we must get back to the same value we had prior to the lookahead.
+        //
+        // Note: any errors at the end of the file that do not precede a regular node, should get
+        // attached to the EOF token.
+        var parseErrorBeforeNextFinishedNode = false;
+        function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) {
+            scriptKind = ts.ensureScriptKind(fileName, scriptKind);
+            initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
+            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
+            clearState();
+            return result;
+        }
+        Parser.parseSourceFile = parseSourceFile;
+        function parseIsolatedEntityName(content, languageVersion) {
+            initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */);
+            // Prime the scanner.
+            nextToken();
+            var entityName = parseEntityName(/*allowReservedWords*/ true);
+            var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length;
+            clearState();
+            return isInvalid ? entityName : undefined;
+        }
+        Parser.parseIsolatedEntityName = parseIsolatedEntityName;
+        function parseJsonText(fileName, sourceText) {
+            initializeState(sourceText, 2 /* ES2015 */, /*syntaxCursor*/ undefined, 6 /* JSON */);
+            // Set source file so that errors will be reported with this file name
+            sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */);
+            var result = sourceFile;
+            // Prime the scanner.
+            nextToken();
+            if (token() === 1 /* EndOfFileToken */) {
+                sourceFile.endOfFileToken = parseTokenNode();
+            }
+            else if (token() === 17 /* OpenBraceToken */ ||
+                lookAhead(function () { return token() === 9 /* StringLiteral */; })) {
+                result.jsonObject = parseObjectLiteralExpression();
+                sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Unexpected_token);
+            }
+            else {
+                parseExpected(17 /* OpenBraceToken */);
+            }
+            sourceFile.parseDiagnostics = parseDiagnostics;
+            clearState();
+            return result;
+        }
+        Parser.parseJsonText = parseJsonText;
+        function getLanguageVariant(scriptKind) {
+            // .tsx and .jsx files are treated as jsx language variant.
+            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */;
+        }
+        function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) {
+            NodeConstructor = ts.objectAllocator.getNodeConstructor();
+            TokenConstructor = ts.objectAllocator.getTokenConstructor();
+            IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor();
+            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
+            sourceText = _sourceText;
+            syntaxCursor = _syntaxCursor;
+            parseDiagnostics = [];
+            parsingContext = 0;
+            identifiers = ts.createMap();
+            identifierCount = 0;
+            nodeCount = 0;
+            contextFlags = scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */ || scriptKind === 6 /* JSON */ ? 65536 /* JavaScriptFile */ : 0 /* None */;
+            parseErrorBeforeNextFinishedNode = false;
+            // Initialize and prime the scanner before parsing the source elements.
+            scanner.setText(sourceText);
+            scanner.setOnError(scanError);
+            scanner.setScriptTarget(languageVersion);
+            scanner.setLanguageVariant(getLanguageVariant(scriptKind));
+        }
+        function clearState() {
+            // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
+            scanner.setText("");
+            scanner.setOnError(undefined);
+            // Clear any data.  We don't want to accidentally hold onto it for too long.
+            parseDiagnostics = undefined;
+            sourceFile = undefined;
+            identifiers = undefined;
+            syntaxCursor = undefined;
+            sourceText = undefined;
+        }
+        function parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind) {
+            sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
+            sourceFile.flags = contextFlags;
+            // Prime the scanner.
+            nextToken();
+            processReferenceComments(sourceFile);
+            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
+            ts.Debug.assert(token() === 1 /* EndOfFileToken */);
+            sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
+            setExternalModuleIndicator(sourceFile);
+            sourceFile.nodeCount = nodeCount;
+            sourceFile.identifierCount = identifierCount;
+            sourceFile.identifiers = identifiers;
+            sourceFile.parseDiagnostics = parseDiagnostics;
+            if (setParentNodes) {
+                fixupParentReferences(sourceFile);
+            }
+            return sourceFile;
+        }
+        function addJSDocComment(node) {
+            var comments = ts.getJSDocCommentRanges(node, sourceFile.text);
+            if (comments) {
+                for (var _i = 0, comments_2 = comments; _i < comments_2.length; _i++) {
+                    var comment = comments_2[_i];
+                    var jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
+                    if (!jsDoc) {
+                        continue;
+                    }
+                    if (!node.jsDoc) {
+                        node.jsDoc = [];
+                    }
+                    node.jsDoc.push(jsDoc);
+                }
+            }
+            return node;
+        }
+        function fixupParentReferences(rootNode) {
+            // normally parent references are set during binding. However, for clients that only need
+            // a syntax tree, and no semantic features, then the binding process is an unnecessary
+            // overhead.  This functions allows us to set all the parents, without all the expense of
+            // binding.
+            var parent = rootNode;
+            forEachChild(rootNode, visitNode);
+            return;
+            function visitNode(n) {
+                // walk down setting parents that differ from the parent we think it should be.  This
+                // allows us to quickly bail out of setting parents for subtrees during incremental
+                // parsing
+                if (n.parent !== parent) {
+                    n.parent = parent;
+                    var saveParent = parent;
+                    parent = n;
+                    forEachChild(n, visitNode);
+                    if (ts.hasJSDocNodes(n)) {
+                        for (var _i = 0, _a = n.jsDoc; _i < _a.length; _i++) {
+                            var jsDoc = _a[_i];
+                            jsDoc.parent = n;
+                            parent = jsDoc;
+                            forEachChild(jsDoc, visitNode);
+                        }
+                    }
+                    parent = saveParent;
+                }
+            }
+        }
+        Parser.fixupParentReferences = fixupParentReferences;
+        function createSourceFile(fileName, languageVersion, scriptKind) {
+            // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
+            // this is quite rare comparing to other nodes and createNode should be as fast as possible
+            var sourceFile = new SourceFileConstructor(265 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
+            nodeCount++;
+            sourceFile.text = sourceText;
+            sourceFile.bindDiagnostics = [];
+            sourceFile.languageVersion = languageVersion;
+            sourceFile.fileName = ts.normalizePath(fileName);
+            sourceFile.languageVariant = getLanguageVariant(scriptKind);
+            sourceFile.isDeclarationFile = ts.fileExtensionIs(sourceFile.fileName, ".d.ts" /* Dts */);
+            sourceFile.scriptKind = scriptKind;
+            return sourceFile;
+        }
+        function setContextFlag(val, flag) {
+            if (val) {
+                contextFlags |= flag;
+            }
+            else {
+                contextFlags &= ~flag;
+            }
+        }
+        function setDisallowInContext(val) {
+            setContextFlag(val, 2048 /* DisallowInContext */);
+        }
+        function setYieldContext(val) {
+            setContextFlag(val, 4096 /* YieldContext */);
+        }
+        function setDecoratorContext(val) {
+            setContextFlag(val, 8192 /* DecoratorContext */);
+        }
+        function setAwaitContext(val) {
+            setContextFlag(val, 16384 /* AwaitContext */);
+        }
+        function doOutsideOfContext(context, func) {
+            // contextFlagsToClear will contain only the context flags that are
+            // currently set that we need to temporarily clear
+            // We don't just blindly reset to the previous flags to ensure
+            // that we do not mutate cached flags for the incremental
+            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
+            // HasAggregatedChildData).
+            var contextFlagsToClear = context & contextFlags;
+            if (contextFlagsToClear) {
+                // clear the requested context flags
+                setContextFlag(/*val*/ false, contextFlagsToClear);
+                var result = func();
+                // restore the context flags we just cleared
+                setContextFlag(/*val*/ true, contextFlagsToClear);
+                return result;
+            }
+            // no need to do anything special as we are not in any of the requested contexts
+            return func();
+        }
+        function doInsideOfContext(context, func) {
+            // contextFlagsToSet will contain only the context flags that
+            // are not currently set that we need to temporarily enable.
+            // We don't just blindly reset to the previous flags to ensure
+            // that we do not mutate cached flags for the incremental
+            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
+            // HasAggregatedChildData).
+            var contextFlagsToSet = context & ~contextFlags;
+            if (contextFlagsToSet) {
+                // set the requested context flags
+                setContextFlag(/*val*/ true, contextFlagsToSet);
+                var result = func();
+                // reset the context flags we just set
+                setContextFlag(/*val*/ false, contextFlagsToSet);
+                return result;
+            }
+            // no need to do anything special as we are already in all of the requested contexts
+            return func();
+        }
+        function allowInAnd(func) {
+            return doOutsideOfContext(2048 /* DisallowInContext */, func);
+        }
+        function disallowInAnd(func) {
+            return doInsideOfContext(2048 /* DisallowInContext */, func);
+        }
+        function doInYieldContext(func) {
+            return doInsideOfContext(4096 /* YieldContext */, func);
+        }
+        function doInDecoratorContext(func) {
+            return doInsideOfContext(8192 /* DecoratorContext */, func);
+        }
+        function doInAwaitContext(func) {
+            return doInsideOfContext(16384 /* AwaitContext */, func);
+        }
+        function doOutsideOfAwaitContext(func) {
+            return doOutsideOfContext(16384 /* AwaitContext */, func);
+        }
+        function doInYieldAndAwaitContext(func) {
+            return doInsideOfContext(4096 /* YieldContext */ | 16384 /* AwaitContext */, func);
+        }
+        function inContext(flags) {
+            return (contextFlags & flags) !== 0;
+        }
+        function inYieldContext() {
+            return inContext(4096 /* YieldContext */);
+        }
+        function inDisallowInContext() {
+            return inContext(2048 /* DisallowInContext */);
+        }
+        function inDecoratorContext() {
+            return inContext(8192 /* DecoratorContext */);
+        }
+        function inAwaitContext() {
+            return inContext(16384 /* AwaitContext */);
+        }
+        function parseErrorAtCurrentToken(message, arg0) {
+            var start = scanner.getTokenPos();
+            var length = scanner.getTextPos() - start;
+            parseErrorAtPosition(start, length, message, arg0);
+        }
+        function parseErrorAtPosition(start, length, message, arg0) {
+            // Don't report another error if it would just be at the same position as the last error.
+            var lastError = ts.lastOrUndefined(parseDiagnostics);
+            if (!lastError || start !== lastError.start) {
+                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0));
+            }
+            // Mark that we've encountered an error.  We'll set an appropriate bit on the next
+            // node we finish so that it can't be reused incrementally.
+            parseErrorBeforeNextFinishedNode = true;
+        }
+        function scanError(message, length) {
+            var pos = scanner.getTextPos();
+            parseErrorAtPosition(pos, length || 0, message);
+        }
+        function getNodePos() {
+            return scanner.getStartPos();
+        }
+        // Use this function to access the current token instead of reading the currentToken
+        // variable. Since function results aren't narrowed in control flow analysis, this ensures
+        // that the type checker doesn't make wrong assumptions about the type of the current
+        // token (e.g. a call to nextToken() changes the current token but the checker doesn't
+        // reason about this side effect).  Mainstream VMs inline simple functions like this, so
+        // there is no performance penalty.
+        function token() {
+            return currentToken;
+        }
+        function nextToken() {
+            return currentToken = scanner.scan();
+        }
+        function reScanGreaterToken() {
+            return currentToken = scanner.reScanGreaterToken();
+        }
+        function reScanSlashToken() {
+            return currentToken = scanner.reScanSlashToken();
+        }
+        function reScanTemplateToken() {
+            return currentToken = scanner.reScanTemplateToken();
+        }
+        function scanJsxIdentifier() {
+            return currentToken = scanner.scanJsxIdentifier();
+        }
+        function scanJsxText() {
+            return currentToken = scanner.scanJsxToken();
+        }
+        function scanJsxAttributeValue() {
+            return currentToken = scanner.scanJsxAttributeValue();
+        }
+        function speculationHelper(callback, isLookAhead) {
+            // Keep track of the state we'll need to rollback to if lookahead fails (or if the
+            // caller asked us to always reset our state).
+            var saveToken = currentToken;
+            var saveParseDiagnosticsLength = parseDiagnostics.length;
+            var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
+            // Note: it is not actually necessary to save/restore the context flags here.  That's
+            // because the saving/restoring of these flags happens naturally through the recursive
+            // descent nature of our parser.  However, we still store this here just so we can
+            // assert that invariant holds.
+            var saveContextFlags = contextFlags;
+            // If we're only looking ahead, then tell the scanner to only lookahead as well.
+            // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the
+            // same.
+            var result = isLookAhead
+                ? scanner.lookAhead(callback)
+                : scanner.tryScan(callback);
+            ts.Debug.assert(saveContextFlags === contextFlags);
+            // If our callback returned something 'falsy' or we're just looking ahead,
+            // then unconditionally restore us to where we were.
+            if (!result || isLookAhead) {
+                currentToken = saveToken;
+                parseDiagnostics.length = saveParseDiagnosticsLength;
+                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
+            }
+            return result;
+        }
+        /** Invokes the provided callback then unconditionally restores the parser to the state it
+         * was in immediately prior to invoking the callback.  The result of invoking the callback
+         * is returned from this function.
+         */
+        function lookAhead(callback) {
+            return speculationHelper(callback, /*isLookAhead*/ true);
+        }
+        /** Invokes the provided callback.  If the callback returns something falsy, then it restores
+         * the parser to the state it was in immediately prior to invoking the callback.  If the
+         * callback returns something truthy, then the parser state is not rolled back.  The result
+         * of invoking the callback is returned from this function.
+         */
+        function tryParse(callback) {
+            return speculationHelper(callback, /*isLookAhead*/ false);
+        }
+        // Ignore strict mode flag because we will report an error in type checker instead.
+        function isIdentifier() {
+            if (token() === 71 /* Identifier */) {
+                return true;
+            }
+            // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is
+            // considered a keyword and is not an identifier.
+            if (token() === 116 /* YieldKeyword */ && inYieldContext()) {
+                return false;
+            }
+            // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
+            // considered a keyword and is not an identifier.
+            if (token() === 121 /* AwaitKeyword */ && inAwaitContext()) {
+                return false;
+            }
+            return token() > 107 /* LastReservedWord */;
+        }
+        function parseExpected(kind, diagnosticMessage, shouldAdvance) {
+            if (shouldAdvance === void 0) { shouldAdvance = true; }
+            if (token() === kind) {
+                if (shouldAdvance) {
+                    nextToken();
+                }
+                return true;
+            }
+            // Report specific message if provided with one.  Otherwise, report generic fallback message.
+            if (diagnosticMessage) {
+                parseErrorAtCurrentToken(diagnosticMessage);
+            }
+            else {
+                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
+            }
+            return false;
+        }
+        function parseOptional(t) {
+            if (token() === t) {
+                nextToken();
+                return true;
+            }
+            return false;
+        }
+        function parseOptionalToken(t) {
+            if (token() === t) {
+                return parseTokenNode();
+            }
+            return undefined;
+        }
+        function parseExpectedToken(t, reportAtCurrentPosition, diagnosticMessage, arg0) {
+            return parseOptionalToken(t) ||
+                createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
+        }
+        function parseTokenNode() {
+            var node = createNode(token());
+            nextToken();
+            return finishNode(node);
+        }
+        function canParseSemicolon() {
+            // If there's a real semicolon, then we can always parse it out.
+            if (token() === 25 /* SemicolonToken */) {
+                return true;
+            }
+            // We can parse out an optional semicolon in ASI cases in the following cases.
+            return token() === 18 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
+        }
+        function parseSemicolon() {
+            if (canParseSemicolon()) {
+                if (token() === 25 /* SemicolonToken */) {
+                    // consume the semicolon if it was explicitly provided.
+                    nextToken();
+                }
+                return true;
+            }
+            else {
+                return parseExpected(25 /* SemicolonToken */);
+            }
+        }
+        // note: this function creates only node
+        function createNode(kind, pos) {
+            nodeCount++;
+            if (!(pos >= 0)) {
+                pos = scanner.getStartPos();
+            }
+            return ts.isNodeKind(kind) ? new NodeConstructor(kind, pos, pos) :
+                kind === 71 /* Identifier */ ? new IdentifierConstructor(kind, pos, pos) :
+                    new TokenConstructor(kind, pos, pos);
+        }
+        function createNodeArray(elements, pos, end) {
+            // Since the element list of a node array is typically created by starting with an empty array and
+            // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
+            // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
+            var length = elements.length;
+            var array = (length >= 1 && length <= 4 ? elements.slice() : elements);
+            array.pos = pos;
+            array.end = end === undefined ? scanner.getStartPos() : end;
+            return array;
+        }
+        function finishNode(node, end) {
+            node.end = end === undefined ? scanner.getStartPos() : end;
+            if (contextFlags) {
+                node.flags |= contextFlags;
+            }
+            // Keep track on the node if we encountered an error while parsing it.  If we did, then
+            // we cannot reuse the node incrementally.  Once we've marked this node, clear out the
+            // flag so that we don't mark any subsequent nodes.
+            if (parseErrorBeforeNextFinishedNode) {
+                parseErrorBeforeNextFinishedNode = false;
+                node.flags |= 32768 /* ThisNodeHasError */;
+            }
+            return node;
+        }
+        function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) {
+            if (reportAtCurrentPosition) {
+                parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
+            }
+            else {
+                parseErrorAtCurrentToken(diagnosticMessage, arg0);
+            }
+            var result = createNode(kind, scanner.getStartPos());
+            if (kind === 71 /* Identifier */) {
+                result.escapedText = "";
+            }
+            else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) {
+                result.text = "";
+            }
+            return finishNode(result);
+        }
+        function internIdentifier(text) {
+            var identifier = identifiers.get(text);
+            if (identifier === undefined) {
+                identifiers.set(text, identifier = text);
+            }
+            return identifier;
+        }
+        // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
+        // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
+        // each identifier in order to reduce memory consumption.
+        function createIdentifier(isIdentifier, diagnosticMessage) {
+            identifierCount++;
+            if (isIdentifier) {
+                var node = createNode(71 /* Identifier */);
+                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
+                if (token() !== 71 /* Identifier */) {
+                    node.originalKeywordKind = token();
+                }
+                node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
+                nextToken();
+                return finishNode(node);
+            }
+            // Only for end of file because the error gets reported incorrectly on embedded script tags.
+            var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */;
+            return createMissingNode(71 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || ts.Diagnostics.Identifier_expected);
+        }
+        function parseIdentifier(diagnosticMessage) {
+            return createIdentifier(isIdentifier(), diagnosticMessage);
+        }
+        function parseIdentifierName(diagnosticMessage) {
+            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
+        }
+        function isLiteralPropertyName() {
+            return ts.tokenIsIdentifierOrKeyword(token()) ||
+                token() === 9 /* StringLiteral */ ||
+                token() === 8 /* NumericLiteral */;
+        }
+        function parsePropertyNameWorker(allowComputedPropertyNames) {
+            if (token() === 9 /* StringLiteral */ || token() === 8 /* NumericLiteral */) {
+                var node = parseLiteralNode();
+                node.text = internIdentifier(node.text);
+                return node;
+            }
+            if (allowComputedPropertyNames && token() === 21 /* OpenBracketToken */) {
+                return parseComputedPropertyName();
+            }
+            return parseIdentifierName();
+        }
+        function parsePropertyName() {
+            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
+        }
+        function parseComputedPropertyName() {
+            // PropertyName [Yield]:
+            //      LiteralPropertyName
+            //      ComputedPropertyName[?Yield]
+            var node = createNode(144 /* ComputedPropertyName */);
+            parseExpected(21 /* OpenBracketToken */);
+            // We parse any expression (including a comma expression). But the grammar
+            // says that only an assignment expression is allowed, so the grammar checker
+            // will error if it sees a comma expression.
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(22 /* CloseBracketToken */);
+            return finishNode(node);
+        }
+        function parseContextualModifier(t) {
+            return token() === t && tryParse(nextTokenCanFollowModifier);
+        }
+        function nextTokenIsOnSameLineAndCanFollowModifier() {
+            nextToken();
+            if (scanner.hasPrecedingLineBreak()) {
+                return false;
+            }
+            return canFollowModifier();
+        }
+        function nextTokenCanFollowModifier() {
+            if (token() === 76 /* ConstKeyword */) {
+                // 'const' is only a modifier if followed by 'enum'.
+                return nextToken() === 83 /* EnumKeyword */;
+            }
+            if (token() === 84 /* ExportKeyword */) {
+                nextToken();
+                if (token() === 79 /* DefaultKeyword */) {
+                    return lookAhead(nextTokenCanFollowDefaultKeyword);
+                }
+                return token() !== 39 /* AsteriskToken */ && token() !== 118 /* AsKeyword */ && token() !== 17 /* OpenBraceToken */ && canFollowModifier();
+            }
+            if (token() === 79 /* DefaultKeyword */) {
+                return nextTokenCanFollowDefaultKeyword();
+            }
+            if (token() === 115 /* StaticKeyword */) {
+                nextToken();
+                return canFollowModifier();
+            }
+            return nextTokenIsOnSameLineAndCanFollowModifier();
+        }
+        function parseAnyContextualModifier() {
+            return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier);
+        }
+        function canFollowModifier() {
+            return token() === 21 /* OpenBracketToken */
+                || token() === 17 /* OpenBraceToken */
+                || token() === 39 /* AsteriskToken */
+                || token() === 24 /* DotDotDotToken */
+                || isLiteralPropertyName();
+        }
+        function nextTokenCanFollowDefaultKeyword() {
+            nextToken();
+            return token() === 75 /* ClassKeyword */ || token() === 89 /* FunctionKeyword */ ||
+                token() === 109 /* InterfaceKeyword */ ||
+                (token() === 117 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
+                (token() === 120 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
+        }
+        // True if positioned at the start of a list element
+        function isListElement(parsingContext, inErrorRecovery) {
+            var node = currentNode(parsingContext);
+            if (node) {
+                return true;
+            }
+            switch (parsingContext) {
+                case 0 /* SourceElements */:
+                case 1 /* BlockStatements */:
+                case 3 /* SwitchClauseStatements */:
+                    // If we're in error recovery, then we don't want to treat ';' as an empty statement.
+                    // The problem is that ';' can show up in far too many contexts, and if we see one
+                    // and assume it's a statement, then we may bail out inappropriately from whatever
+                    // we're parsing.  For example, if we have a semicolon in the middle of a class, then
+                    // we really don't want to assume the class is over and we're on a statement in the
+                    // outer module.  We just want to consume and move on.
+                    return !(token() === 25 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
+                case 2 /* SwitchClauses */:
+                    return token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */;
+                case 4 /* TypeMembers */:
+                    return lookAhead(isTypeMemberStart);
+                case 5 /* ClassMembers */:
+                    // We allow semicolons as class elements (as specified by ES6) as long as we're
+                    // not in error recovery.  If we're in error recovery, we don't want an errant
+                    // semicolon to be treated as a class member (since they're almost always used
+                    // for statements.
+                    return lookAhead(isClassMemberStart) || (token() === 25 /* SemicolonToken */ && !inErrorRecovery);
+                case 6 /* EnumMembers */:
+                    // Include open bracket computed properties. This technically also lets in indexers,
+                    // which would be a candidate for improved error reporting.
+                    return token() === 21 /* OpenBracketToken */ || isLiteralPropertyName();
+                case 12 /* ObjectLiteralMembers */:
+                    return token() === 21 /* OpenBracketToken */ || token() === 39 /* AsteriskToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName();
+                case 17 /* RestProperties */:
+                    return isLiteralPropertyName();
+                case 9 /* ObjectBindingElements */:
+                    return token() === 21 /* OpenBracketToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName();
+                case 7 /* HeritageClauseElement */:
+                    // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
+                    // That way we won't consume the body of a class in its heritage clause.
+                    if (token() === 17 /* OpenBraceToken */) {
+                        return lookAhead(isValidHeritageClauseObjectLiteral);
+                    }
+                    if (!inErrorRecovery) {
+                        return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
+                    }
+                    else {
+                        // If we're in error recovery we tighten up what we're willing to match.
+                        // That way we don't treat something like "this" as a valid heritage clause
+                        // element during recovery.
+                        return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
+                    }
+                case 8 /* VariableDeclarations */:
+                    return isIdentifierOrPattern();
+                case 10 /* ArrayBindingElements */:
+                    return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern();
+                case 18 /* TypeParameters */:
+                    return isIdentifier();
+                case 11 /* ArgumentExpressions */:
+                case 15 /* ArrayLiteralMembers */:
+                    return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isStartOfExpression();
+                case 16 /* Parameters */:
+                    return isStartOfParameter();
+                case 19 /* TypeArguments */:
+                case 20 /* TupleElementTypes */:
+                    return token() === 26 /* CommaToken */ || isStartOfType();
+                case 21 /* HeritageClauses */:
+                    return isHeritageClause();
+                case 22 /* ImportOrExportSpecifiers */:
+                    return ts.tokenIsIdentifierOrKeyword(token());
+                case 13 /* JsxAttributes */:
+                    return ts.tokenIsIdentifierOrKeyword(token()) || token() === 17 /* OpenBraceToken */;
+                case 14 /* JsxChildren */:
+                    return true;
+            }
+            ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
+        }
+        function isValidHeritageClauseObjectLiteral() {
+            ts.Debug.assert(token() === 17 /* OpenBraceToken */);
+            if (nextToken() === 18 /* CloseBraceToken */) {
+                // if we see  "extends {}" then only treat the {} as what we're extending (and not
+                // the class body) if we have:
+                //
+                //      extends {} {
+                //      extends {},
+                //      extends {} extends
+                //      extends {} implements
+                var next = nextToken();
+                return next === 26 /* CommaToken */ || next === 17 /* OpenBraceToken */ || next === 85 /* ExtendsKeyword */ || next === 108 /* ImplementsKeyword */;
+            }
+            return true;
+        }
+        function nextTokenIsIdentifier() {
+            nextToken();
+            return isIdentifier();
+        }
+        function nextTokenIsIdentifierOrKeyword() {
+            nextToken();
+            return ts.tokenIsIdentifierOrKeyword(token());
+        }
+        function isHeritageClauseExtendsOrImplementsKeyword() {
+            if (token() === 108 /* ImplementsKeyword */ ||
+                token() === 85 /* ExtendsKeyword */) {
+                return lookAhead(nextTokenIsStartOfExpression);
+            }
+            return false;
+        }
+        function nextTokenIsStartOfExpression() {
+            nextToken();
+            return isStartOfExpression();
+        }
+        // True if positioned at a list terminator
+        function isListTerminator(kind) {
+            if (token() === 1 /* EndOfFileToken */) {
+                // Being at the end of the file ends all lists.
+                return true;
+            }
+            switch (kind) {
+                case 1 /* BlockStatements */:
+                case 2 /* SwitchClauses */:
+                case 4 /* TypeMembers */:
+                case 5 /* ClassMembers */:
+                case 6 /* EnumMembers */:
+                case 12 /* ObjectLiteralMembers */:
+                case 9 /* ObjectBindingElements */:
+                case 22 /* ImportOrExportSpecifiers */:
+                    return token() === 18 /* CloseBraceToken */;
+                case 3 /* SwitchClauseStatements */:
+                    return token() === 18 /* CloseBraceToken */ || token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */;
+                case 7 /* HeritageClauseElement */:
+                    return token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
+                case 8 /* VariableDeclarations */:
+                    return isVariableDeclaratorListTerminator();
+                case 18 /* TypeParameters */:
+                    // Tokens other than '>' are here for better error recovery
+                    return token() === 29 /* GreaterThanToken */ || token() === 19 /* OpenParenToken */ || token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
+                case 11 /* ArgumentExpressions */:
+                    // Tokens other than ')' are here for better error recovery
+                    return token() === 20 /* CloseParenToken */ || token() === 25 /* SemicolonToken */;
+                case 15 /* ArrayLiteralMembers */:
+                case 20 /* TupleElementTypes */:
+                case 10 /* ArrayBindingElements */:
+                    return token() === 22 /* CloseBracketToken */;
+                case 16 /* Parameters */:
+                case 17 /* RestProperties */:
+                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
+                    return token() === 20 /* CloseParenToken */ || token() === 22 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
+                case 19 /* TypeArguments */:
+                    // All other tokens should cause the type-argument to terminate except comma token
+                    return token() !== 26 /* CommaToken */;
+                case 21 /* HeritageClauses */:
+                    return token() === 17 /* OpenBraceToken */ || token() === 18 /* CloseBraceToken */;
+                case 13 /* JsxAttributes */:
+                    return token() === 29 /* GreaterThanToken */ || token() === 41 /* SlashToken */;
+                case 14 /* JsxChildren */:
+                    return token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
+            }
+        }
+        function isVariableDeclaratorListTerminator() {
+            // If we can consume a semicolon (either explicitly, or with ASI), then consider us done
+            // with parsing the list of  variable declarators.
+            if (canParseSemicolon()) {
+                return true;
+            }
+            // in the case where we're parsing the variable declarator of a 'for-in' statement, we
+            // are done if we see an 'in' keyword in front of us. Same with for-of
+            if (isInOrOfKeyword(token())) {
+                return true;
+            }
+            // ERROR RECOVERY TWEAK:
+            // For better error recovery, if we see an '=>' then we just stop immediately.  We've got an
+            // arrow function here and it's going to be very unlikely that we'll resynchronize and get
+            // another variable declaration.
+            if (token() === 36 /* EqualsGreaterThanToken */) {
+                return true;
+            }
+            // Keep trying to parse out variable declarators.
+            return false;
+        }
+        // True if positioned at element or terminator of the current list or any enclosing list
+        function isInSomeParsingContext() {
+            for (var kind = 0; kind < 23 /* Count */; kind++) {
+                if (parsingContext & (1 << kind)) {
+                    if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        // Parses a list of elements
+        function parseList(kind, parseElement) {
+            var saveParsingContext = parsingContext;
+            parsingContext |= 1 << kind;
+            var list = [];
+            var listPos = getNodePos();
+            while (!isListTerminator(kind)) {
+                if (isListElement(kind, /*inErrorRecovery*/ false)) {
+                    var element = parseListElement(kind, parseElement);
+                    list.push(element);
+                    continue;
+                }
+                if (abortParsingListOrMoveToNextToken(kind)) {
+                    break;
+                }
+            }
+            parsingContext = saveParsingContext;
+            return createNodeArray(list, listPos);
+        }
+        function parseListElement(parsingContext, parseElement) {
+            var node = currentNode(parsingContext);
+            if (node) {
+                return consumeNode(node);
+            }
+            return parseElement();
+        }
+        function currentNode(parsingContext) {
+            // If there is an outstanding parse error that we've encountered, but not attached to
+            // some node, then we cannot get a node from the old source tree.  This is because we
+            // want to mark the next node we encounter as being unusable.
+            //
+            // Note: This may be too conservative.  Perhaps we could reuse the node and set the bit
+            // on it (or its leftmost child) as having the error.  For now though, being conservative
+            // is nice and likely won't ever affect perf.
+            if (parseErrorBeforeNextFinishedNode) {
+                return undefined;
+            }
+            if (!syntaxCursor) {
+                // if we don't have a cursor, we could never return a node from the old tree.
+                return undefined;
+            }
+            var node = syntaxCursor.currentNode(scanner.getStartPos());
+            // Can't reuse a missing node.
+            if (ts.nodeIsMissing(node)) {
+                return undefined;
+            }
+            // Can't reuse a node that intersected the change range.
+            if (node.intersectsChange) {
+                return undefined;
+            }
+            // Can't reuse a node that contains a parse error.  This is necessary so that we
+            // produce the same set of errors again.
+            if (ts.containsParseError(node)) {
+                return undefined;
+            }
+            // We can only reuse a node if it was parsed under the same strict mode that we're
+            // currently in.  i.e. if we originally parsed a node in non-strict mode, but then
+            // the user added 'using strict' at the top of the file, then we can't use that node
+            // again as the presence of strict mode may cause us to parse the tokens in the file
+            // differently.
+            //
+            // Note: we *can* reuse tokens when the strict mode changes.  That's because tokens
+            // are unaffected by strict mode.  It's just the parser will decide what to do with it
+            // differently depending on what mode it is in.
+            //
+            // This also applies to all our other context flags as well.
+            var nodeContextFlags = node.flags & 96256 /* ContextFlags */;
+            if (nodeContextFlags !== contextFlags) {
+                return undefined;
+            }
+            // Ok, we have a node that looks like it could be reused.  Now verify that it is valid
+            // in the current list parsing context that we're currently at.
+            if (!canReuseNode(node, parsingContext)) {
+                return undefined;
+            }
+            return node;
+        }
+        function consumeNode(node) {
+            // Move the scanner so it is after the node we just consumed.
+            scanner.setTextPos(node.end);
+            nextToken();
+            return node;
+        }
+        function canReuseNode(node, parsingContext) {
+            switch (parsingContext) {
+                case 5 /* ClassMembers */:
+                    return isReusableClassMember(node);
+                case 2 /* SwitchClauses */:
+                    return isReusableSwitchClause(node);
+                case 0 /* SourceElements */:
+                case 1 /* BlockStatements */:
+                case 3 /* SwitchClauseStatements */:
+                    return isReusableStatement(node);
+                case 6 /* EnumMembers */:
+                    return isReusableEnumMember(node);
+                case 4 /* TypeMembers */:
+                    return isReusableTypeMember(node);
+                case 8 /* VariableDeclarations */:
+                    return isReusableVariableDeclaration(node);
+                case 16 /* Parameters */:
+                    return isReusableParameter(node);
+                case 17 /* RestProperties */:
+                    return false;
+                // Any other lists we do not care about reusing nodes in.  But feel free to add if
+                // you can do so safely.  Danger areas involve nodes that may involve speculative
+                // parsing.  If speculative parsing is involved with the node, then the range the
+                // parser reached while looking ahead might be in the edited range (see the example
+                // in canReuseVariableDeclaratorNode for a good case of this).
+                case 21 /* HeritageClauses */:
+                // This would probably be safe to reuse.  There is no speculative parsing with
+                // heritage clauses.
+                case 18 /* TypeParameters */:
+                // This would probably be safe to reuse.  There is no speculative parsing with
+                // type parameters.  Note that that's because type *parameters* only occur in
+                // unambiguous *type* contexts.  While type *arguments* occur in very ambiguous
+                // *expression* contexts.
+                case 20 /* TupleElementTypes */:
+                // This would probably be safe to reuse.  There is no speculative parsing with
+                // tuple types.
+                // Technically, type argument list types are probably safe to reuse.  While
+                // speculative parsing is involved with them (since type argument lists are only
+                // produced from speculative parsing a < as a type argument list), we only have
+                // the types because speculative parsing succeeded.  Thus, the lookahead never
+                // went past the end of the list and rewound.
+                case 19 /* TypeArguments */:
+                // Note: these are almost certainly not safe to ever reuse.  Expressions commonly
+                // need a large amount of lookahead, and we should not reuse them as they may
+                // have actually intersected the edit.
+                case 11 /* ArgumentExpressions */:
+                // This is not safe to reuse for the same reason as the 'AssignmentExpression'
+                // cases.  i.e. a property assignment may end with an expression, and thus might
+                // have lookahead far beyond it's old node.
+                case 12 /* ObjectLiteralMembers */:
+                // This is probably not safe to reuse.  There can be speculative parsing with
+                // type names in a heritage clause.  There can be generic names in the type
+                // name list, and there can be left hand side expressions (which can have type
+                // arguments.)
+                case 7 /* HeritageClauseElement */:
+                // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
+                // on any given element. Same for children.
+                case 13 /* JsxAttributes */:
+                case 14 /* JsxChildren */:
+            }
+            return false;
+        }
+        function isReusableClassMember(node) {
+            if (node) {
+                switch (node.kind) {
+                    case 152 /* Constructor */:
+                    case 157 /* IndexSignature */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 149 /* PropertyDeclaration */:
+                    case 206 /* SemicolonClassElement */:
+                        return true;
+                    case 151 /* MethodDeclaration */:
+                        // Method declarations are not necessarily reusable.  An object-literal
+                        // may have a method calls "constructor(...)" and we must reparse that
+                        // into an actual .ConstructorDeclaration.
+                        var methodDeclaration = node;
+                        var nameIsConstructor = methodDeclaration.name.kind === 71 /* Identifier */ &&
+                            methodDeclaration.name.originalKeywordKind === 123 /* ConstructorKeyword */;
+                        return !nameIsConstructor;
+                }
+            }
+            return false;
+        }
+        function isReusableSwitchClause(node) {
+            if (node) {
+                switch (node.kind) {
+                    case 257 /* CaseClause */:
+                    case 258 /* DefaultClause */:
+                        return true;
+                }
+            }
+            return false;
+        }
+        function isReusableStatement(node) {
+            if (node) {
+                switch (node.kind) {
+                    case 228 /* FunctionDeclaration */:
+                    case 208 /* VariableStatement */:
+                    case 207 /* Block */:
+                    case 211 /* IfStatement */:
+                    case 210 /* ExpressionStatement */:
+                    case 223 /* ThrowStatement */:
+                    case 219 /* ReturnStatement */:
+                    case 221 /* SwitchStatement */:
+                    case 218 /* BreakStatement */:
+                    case 217 /* ContinueStatement */:
+                    case 215 /* ForInStatement */:
+                    case 216 /* ForOfStatement */:
+                    case 214 /* ForStatement */:
+                    case 213 /* WhileStatement */:
+                    case 220 /* WithStatement */:
+                    case 209 /* EmptyStatement */:
+                    case 224 /* TryStatement */:
+                    case 222 /* LabeledStatement */:
+                    case 212 /* DoStatement */:
+                    case 225 /* DebuggerStatement */:
+                    case 238 /* ImportDeclaration */:
+                    case 237 /* ImportEqualsDeclaration */:
+                    case 244 /* ExportDeclaration */:
+                    case 243 /* ExportAssignment */:
+                    case 233 /* ModuleDeclaration */:
+                    case 229 /* ClassDeclaration */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 231 /* TypeAliasDeclaration */:
+                        return true;
+                }
+            }
+            return false;
+        }
+        function isReusableEnumMember(node) {
+            return node.kind === 264 /* EnumMember */;
+        }
+        function isReusableTypeMember(node) {
+            if (node) {
+                switch (node.kind) {
+                    case 156 /* ConstructSignature */:
+                    case 150 /* MethodSignature */:
+                    case 157 /* IndexSignature */:
+                    case 148 /* PropertySignature */:
+                    case 155 /* CallSignature */:
+                        return true;
+                }
+            }
+            return false;
+        }
+        function isReusableVariableDeclaration(node) {
+            if (node.kind !== 226 /* VariableDeclaration */) {
+                return false;
+            }
+            // Very subtle incremental parsing bug.  Consider the following code:
+            //
+            //      let v = new List < A, B
+            //
+            // This is actually legal code.  It's a list of variable declarators "v = new List<A"
+            // on one side and "B" on the other. If you then change that to:
+            //
+            //      let v = new List < A, B >()
+            //
+            // then we have a problem.  "v = new List<A" doesn't intersect the change range, so we
+            // start reparsing at "B" and we completely fail to handle this properly.
+            //
+            // In order to prevent this, we do not allow a variable declarator to be reused if it
+            // has an initializer.
+            var variableDeclarator = node;
+            return variableDeclarator.initializer === undefined;
+        }
+        function isReusableParameter(node) {
+            if (node.kind !== 146 /* Parameter */) {
+                return false;
+            }
+            // See the comment in isReusableVariableDeclaration for why we do this.
+            var parameter = node;
+            return parameter.initializer === undefined;
+        }
+        // Returns true if we should abort parsing.
+        function abortParsingListOrMoveToNextToken(kind) {
+            parseErrorAtCurrentToken(parsingContextErrors(kind));
+            if (isInSomeParsingContext()) {
+                return true;
+            }
+            nextToken();
+            return false;
+        }
+        function parsingContextErrors(context) {
+            switch (context) {
+                case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
+                case 1 /* BlockStatements */: return ts.Diagnostics.Declaration_or_statement_expected;
+                case 2 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
+                case 3 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
+                case 17 /* RestProperties */: // fallthrough
+                case 4 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
+                case 5 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
+                case 6 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
+                case 7 /* HeritageClauseElement */: return ts.Diagnostics.Expression_expected;
+                case 8 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
+                case 9 /* ObjectBindingElements */: return ts.Diagnostics.Property_destructuring_pattern_expected;
+                case 10 /* ArrayBindingElements */: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
+                case 11 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
+                case 12 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
+                case 15 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
+                case 16 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
+                case 18 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
+                case 19 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
+                case 20 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
+                case 21 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
+                case 22 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
+                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
+                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
+            }
+        }
+        // Parses a comma-delimited list of elements
+        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
+            var saveParsingContext = parsingContext;
+            parsingContext |= 1 << kind;
+            var list = [];
+            var listPos = getNodePos();
+            var commaStart = -1; // Meaning the previous token was not a comma
+            while (true) {
+                if (isListElement(kind, /*inErrorRecovery*/ false)) {
+                    var startPos = scanner.getStartPos();
+                    list.push(parseListElement(kind, parseElement));
+                    commaStart = scanner.getTokenPos();
+                    if (parseOptional(26 /* CommaToken */)) {
+                        // No need to check for a zero length node since we know we parsed a comma
+                        continue;
+                    }
+                    commaStart = -1; // Back to the state where the last token was not a comma
+                    if (isListTerminator(kind)) {
+                        break;
+                    }
+                    // We didn't get a comma, and the list wasn't terminated, explicitly parse
+                    // out a comma so we give a good error message.
+                    parseExpected(26 /* CommaToken */);
+                    // If the token was a semicolon, and the caller allows that, then skip it and
+                    // continue.  This ensures we get back on track and don't result in tons of
+                    // parse errors.  For example, this can happen when people do things like use
+                    // a semicolon to delimit object literal members.   Note: we'll have already
+                    // reported an error when we called parseExpected above.
+                    if (considerSemicolonAsDelimiter && token() === 25 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
+                        nextToken();
+                    }
+                    if (startPos === scanner.getStartPos()) {
+                        // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
+                        // Consume a token to advance the parser in some way and avoid an infinite loop
+                        // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
+                        // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
+                        nextToken();
+                    }
+                    continue;
+                }
+                if (isListTerminator(kind)) {
+                    break;
+                }
+                if (abortParsingListOrMoveToNextToken(kind)) {
+                    break;
+                }
+            }
+            parsingContext = saveParsingContext;
+            var result = createNodeArray(list, listPos);
+            // Recording the trailing comma is deliberately done after the previous
+            // loop, and not just if we see a list terminator. This is because the list
+            // may have ended incorrectly, but it is still important to know if there
+            // was a trailing comma.
+            // Check if the last token was a comma.
+            if (commaStart >= 0) {
+                // Always preserve a trailing comma by marking it on the NodeArray
+                result.hasTrailingComma = true;
+            }
+            return result;
+        }
+        function createMissingList() {
+            return createNodeArray([], getNodePos());
+        }
+        function parseBracketedList(kind, parseElement, open, close) {
+            if (parseExpected(open)) {
+                var result = parseDelimitedList(kind, parseElement);
+                parseExpected(close);
+                return result;
+            }
+            return createMissingList();
+        }
+        function parseEntityName(allowReservedWords, diagnosticMessage) {
+            var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
+            var dotPos = scanner.getStartPos();
+            while (parseOptional(23 /* DotToken */)) {
+                if (token() === 27 /* LessThanToken */) {
+                    // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting
+                    entity.jsdocDotPos = dotPos;
+                    break;
+                }
+                dotPos = scanner.getStartPos();
+                entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords));
+            }
+            return entity;
+        }
+        function createQualifiedName(entity, name) {
+            var node = createNode(143 /* QualifiedName */, entity.pos);
+            node.left = entity;
+            node.right = name;
+            return finishNode(node);
+        }
+        function parseRightSideOfDot(allowIdentifierNames) {
+            // Technically a keyword is valid here as all identifiers and keywords are identifier names.
+            // However, often we'll encounter this in error situations when the identifier or keyword
+            // is actually starting another valid construct.
+            //
+            // So, we check for the following specific case:
+            //
+            //      name.
+            //      identifierOrKeyword identifierNameOrKeyword
+            //
+            // Note: the newlines are important here.  For example, if that above code
+            // were rewritten into:
+            //
+            //      name.identifierOrKeyword
+            //      identifierNameOrKeyword
+            //
+            // Then we would consider it valid.  That's because ASI would take effect and
+            // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
+            // In the first case though, ASI will not take effect because there is not a
+            // line terminator after the identifier or keyword.
+            if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) {
+                var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
+                if (matchesPattern) {
+                    // Report that we need an identifier.  However, report it right after the dot,
+                    // and not on the next token.  This is because the next token might actually
+                    // be an identifier and the error would be quite confusing.
+                    return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
+                }
+            }
+            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
+        }
+        function parseTemplateExpression() {
+            var template = createNode(196 /* TemplateExpression */);
+            template.head = parseTemplateHead();
+            ts.Debug.assert(template.head.kind === 14 /* TemplateHead */, "Template head has wrong token kind");
+            var list = [];
+            var listPos = getNodePos();
+            do {
+                list.push(parseTemplateSpan());
+            } while (ts.lastOrUndefined(list).literal.kind === 15 /* TemplateMiddle */);
+            template.templateSpans = createNodeArray(list, listPos);
+            return finishNode(template);
+        }
+        function parseTemplateSpan() {
+            var span = createNode(205 /* TemplateSpan */);
+            span.expression = allowInAnd(parseExpression);
+            var literal;
+            if (token() === 18 /* CloseBraceToken */) {
+                reScanTemplateToken();
+                literal = parseTemplateMiddleOrTemplateTail();
+            }
+            else {
+                literal = parseExpectedToken(16 /* TemplateTail */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(18 /* CloseBraceToken */));
+            }
+            span.literal = literal;
+            return finishNode(span);
+        }
+        function parseLiteralNode() {
+            return parseLiteralLikeNode(token());
+        }
+        function parseTemplateHead() {
+            var fragment = parseLiteralLikeNode(token());
+            ts.Debug.assert(fragment.kind === 14 /* TemplateHead */, "Template head has wrong token kind");
+            return fragment;
+        }
+        function parseTemplateMiddleOrTemplateTail() {
+            var fragment = parseLiteralLikeNode(token());
+            ts.Debug.assert(fragment.kind === 15 /* TemplateMiddle */ || fragment.kind === 16 /* TemplateTail */, "Template fragment has wrong token kind");
+            return fragment;
+        }
+        function parseLiteralLikeNode(kind) {
+            var node = createNode(kind);
+            var text = scanner.getTokenValue();
+            node.text = text;
+            if (scanner.hasExtendedUnicodeEscape()) {
+                node.hasExtendedUnicodeEscape = true;
+            }
+            if (scanner.isUnterminated()) {
+                node.isUnterminated = true;
+            }
+            // Octal literals are not allowed in strict mode or ES5
+            // Note that theoretically the following condition would hold true literals like 009,
+            // which is not octal.But because of how the scanner separates the tokens, we would
+            // never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
+            // We also do not need to check for negatives because any prefix operator would be part of a
+            // parent unary expression.
+            if (node.kind === 8 /* NumericLiteral */) {
+                node.numericLiteralFlags = scanner.getNumericLiteralFlags();
+            }
+            nextToken();
+            finishNode(node);
+            return node;
+        }
+        // TYPES
+        function parseTypeReference() {
+            var node = createNode(159 /* TypeReference */);
+            node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
+            if (!scanner.hasPrecedingLineBreak() && token() === 27 /* LessThanToken */) {
+                node.typeArguments = parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */);
+            }
+            return finishNode(node);
+        }
+        function parseThisTypePredicate(lhs) {
+            nextToken();
+            var node = createNode(158 /* TypePredicate */, lhs.pos);
+            node.parameterName = lhs;
+            node.type = parseType();
+            return finishNode(node);
+        }
+        function parseThisTypeNode() {
+            var node = createNode(169 /* ThisType */);
+            nextToken();
+            return finishNode(node);
+        }
+        function parseJSDocAllType() {
+            var result = createNode(268 /* JSDocAllType */);
+            nextToken();
+            return finishNode(result);
+        }
+        function parseJSDocUnknownOrNullableType() {
+            var pos = scanner.getStartPos();
+            // skip the ?
+            nextToken();
+            // Need to lookahead to decide if this is a nullable or unknown type.
+            // Here are cases where we'll pick the unknown type:
+            //
+            //      Foo(?,
+            //      { a: ? }
+            //      Foo(?)
+            //      Foo<?>
+            //      Foo(?=
+            //      (?|
+            if (token() === 26 /* CommaToken */ ||
+                token() === 18 /* CloseBraceToken */ ||
+                token() === 20 /* CloseParenToken */ ||
+                token() === 29 /* GreaterThanToken */ ||
+                token() === 58 /* EqualsToken */ ||
+                token() === 49 /* BarToken */) {
+                var result = createNode(269 /* JSDocUnknownType */, pos);
+                return finishNode(result);
+            }
+            else {
+                var result = createNode(270 /* JSDocNullableType */, pos);
+                result.type = parseType();
+                return finishNode(result);
+            }
+        }
+        function parseJSDocFunctionType() {
+            if (lookAhead(nextTokenIsOpenParen)) {
+                var result = createNode(273 /* JSDocFunctionType */);
+                nextToken();
+                fillSignature(56 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result);
+                return addJSDocComment(finishNode(result));
+            }
+            var node = createNode(159 /* TypeReference */);
+            node.typeName = parseIdentifierName();
+            return finishNode(node);
+        }
+        function parseJSDocParameter() {
+            var parameter = createNode(146 /* Parameter */);
+            if (token() === 99 /* ThisKeyword */ || token() === 94 /* NewKeyword */) {
+                parameter.name = parseIdentifierName();
+                parseExpected(56 /* ColonToken */);
+            }
+            parameter.type = parseType();
+            return finishNode(parameter);
+        }
+        function parseJSDocNodeWithType(kind) {
+            var result = createNode(kind);
+            nextToken();
+            result.type = parseNonArrayType();
+            return finishNode(result);
+        }
+        function parseTypeQuery() {
+            var node = createNode(162 /* TypeQuery */);
+            parseExpected(103 /* TypeOfKeyword */);
+            node.exprName = parseEntityName(/*allowReservedWords*/ true);
+            return finishNode(node);
+        }
+        function parseTypeParameter() {
+            var node = createNode(145 /* TypeParameter */);
+            node.name = parseIdentifier();
+            if (parseOptional(85 /* ExtendsKeyword */)) {
+                // It's not uncommon for people to write improper constraints to a generic.  If the
+                // user writes a constraint that is an expression and not an actual type, then parse
+                // it out as an expression (so we can recover well), but report that a type is needed
+                // instead.
+                if (isStartOfType() || !isStartOfExpression()) {
+                    node.constraint = parseType();
+                }
+                else {
+                    // It was not a type, and it looked like an expression.  Parse out an expression
+                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
+                    // and not parseExpression here.  If the user has:
+                    //
+                    //      <T extends "">
+                    //
+                    // We do *not* want to consume the  >  as we're consuming the expression for "".
+                    node.expression = parseUnaryExpressionOrHigher();
+                }
+            }
+            if (parseOptional(58 /* EqualsToken */)) {
+                node.default = parseType();
+            }
+            return finishNode(node);
+        }
+        function parseTypeParameters() {
+            if (token() === 27 /* LessThanToken */) {
+                return parseBracketedList(18 /* TypeParameters */, parseTypeParameter, 27 /* LessThanToken */, 29 /* GreaterThanToken */);
+            }
+        }
+        function parseParameterType() {
+            if (parseOptional(56 /* ColonToken */)) {
+                return parseType();
+            }
+            return undefined;
+        }
+        function isStartOfParameter() {
+            return token() === 24 /* DotDotDotToken */ ||
+                isIdentifierOrPattern() ||
+                ts.isModifierKind(token()) ||
+                token() === 57 /* AtToken */ ||
+                isStartOfType(/*inStartOfParameter*/ true);
+        }
+        function parseParameter(requireEqualsToken) {
+            var node = createNode(146 /* Parameter */);
+            if (token() === 99 /* ThisKeyword */) {
+                node.name = createIdentifier(/*isIdentifier*/ true);
+                node.type = parseParameterType();
+                return finishNode(node);
+            }
+            node.decorators = parseDecorators();
+            node.modifiers = parseModifiers();
+            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
+            // FormalParameter [Yield,Await]:
+            //      BindingElement[?Yield,?Await]
+            node.name = parseIdentifierOrPattern();
+            if (ts.getFullWidth(node.name) === 0 && !ts.hasModifiers(node) && ts.isModifierKind(token())) {
+                // in cases like
+                // 'use strict'
+                // function foo(static)
+                // isParameter('static') === true, because of isModifier('static')
+                // however 'static' is not a legal identifier in a strict mode.
+                // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
+                // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
+                // to avoid this we'll advance cursor to the next token.
+                nextToken();
+            }
+            node.questionToken = parseOptionalToken(55 /* QuestionToken */);
+            node.type = parseParameterType();
+            node.initializer = parseInitializer(/*inParameter*/ true, requireEqualsToken);
+            return addJSDocComment(finishNode(node));
+        }
+        function fillSignature(returnToken, flags, signature) {
+            if (!(flags & 32 /* JSDoc */)) {
+                signature.typeParameters = parseTypeParameters();
+            }
+            signature.parameters = parseParameterList(flags);
+            signature.type = parseReturnType(returnToken, !!(flags & 4 /* Type */));
+        }
+        function parseReturnType(returnToken, isType) {
+            return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined;
+        }
+        function shouldParseReturnType(returnToken, isType) {
+            if (returnToken === 36 /* EqualsGreaterThanToken */) {
+                parseExpected(returnToken);
+                return true;
+            }
+            else if (parseOptional(56 /* ColonToken */)) {
+                return true;
+            }
+            else if (isType && token() === 36 /* EqualsGreaterThanToken */) {
+                // This is easy to get backward, especially in type contexts, so parse the type anyway
+                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */));
+                nextToken();
+                return true;
+            }
+            return false;
+        }
+        function parseParameterList(flags) {
+            // FormalParameters [Yield,Await]: (modified)
+            //      [empty]
+            //      FormalParameterList[?Yield,Await]
+            //
+            // FormalParameter[Yield,Await]: (modified)
+            //      BindingElement[?Yield,Await]
+            //
+            // BindingElement [Yield,Await]: (modified)
+            //      SingleNameBinding[?Yield,?Await]
+            //      BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
+            //
+            // SingleNameBinding [Yield,Await]:
+            //      BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
+            if (parseExpected(19 /* OpenParenToken */)) {
+                var savedYieldContext = inYieldContext();
+                var savedAwaitContext = inAwaitContext();
+                setYieldContext(!!(flags & 1 /* Yield */));
+                setAwaitContext(!!(flags & 2 /* Await */));
+                var result = parseDelimitedList(16 /* Parameters */, flags & 32 /* JSDoc */ ? parseJSDocParameter : function () { return parseParameter(!!(flags & 8 /* RequireCompleteParameterList */)); });
+                setYieldContext(savedYieldContext);
+                setAwaitContext(savedAwaitContext);
+                if (!parseExpected(20 /* CloseParenToken */) && (flags & 8 /* RequireCompleteParameterList */)) {
+                    // Caller insisted that we had to end with a )   We didn't.  So just return
+                    // undefined here.
+                    return undefined;
+                }
+                return result;
+            }
+            // We didn't even have an open paren.  If the caller requires a complete parameter list,
+            // we definitely can't provide that.  However, if they're ok with an incomplete one,
+            // then just return an empty set of parameters.
+            return (flags & 8 /* RequireCompleteParameterList */) ? undefined : createMissingList();
+        }
+        function parseTypeMemberSemicolon() {
+            // We allow type members to be separated by commas or (possibly ASI) semicolons.
+            // First check if it was a comma.  If so, we're done with the member.
+            if (parseOptional(26 /* CommaToken */)) {
+                return;
+            }
+            // Didn't have a comma.  We must have a (possible ASI) semicolon.
+            parseSemicolon();
+        }
+        function parseSignatureMember(kind) {
+            var node = createNode(kind);
+            if (kind === 156 /* ConstructSignature */) {
+                parseExpected(94 /* NewKeyword */);
+            }
+            fillSignature(56 /* ColonToken */, 4 /* Type */, node);
+            parseTypeMemberSemicolon();
+            return addJSDocComment(finishNode(node));
+        }
+        function isIndexSignature() {
+            if (token() !== 21 /* OpenBracketToken */) {
+                return false;
+            }
+            return lookAhead(isUnambiguouslyIndexSignature);
+        }
+        function isUnambiguouslyIndexSignature() {
+            // The only allowed sequence is:
+            //
+            //   [id:
+            //
+            // However, for error recovery, we also check the following cases:
+            //
+            //   [...
+            //   [id,
+            //   [id?,
+            //   [id?:
+            //   [id?]
+            //   [public id
+            //   [private id
+            //   [protected id
+            //   []
+            //
+            nextToken();
+            if (token() === 24 /* DotDotDotToken */ || token() === 22 /* CloseBracketToken */) {
+                return true;
+            }
+            if (ts.isModifierKind(token())) {
+                nextToken();
+                if (isIdentifier()) {
+                    return true;
+                }
+            }
+            else if (!isIdentifier()) {
+                return false;
+            }
+            else {
+                // Skip the identifier
+                nextToken();
+            }
+            // A colon signifies a well formed indexer
+            // A comma should be a badly formed indexer because comma expressions are not allowed
+            // in computed properties.
+            if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */) {
+                return true;
+            }
+            // Question mark could be an indexer with an optional property,
+            // or it could be a conditional expression in a computed property.
+            if (token() !== 55 /* QuestionToken */) {
+                return false;
+            }
+            // If any of the following tokens are after the question mark, it cannot
+            // be a conditional expression, so treat it as an indexer.
+            nextToken();
+            return token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || token() === 22 /* CloseBracketToken */;
+        }
+        function parseIndexSignatureDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(157 /* IndexSignature */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */);
+            node.type = parseTypeAnnotation();
+            parseTypeMemberSemicolon();
+            return addJSDocComment(finishNode(node));
+        }
+        function parsePropertyOrMethodSignature(fullStart, modifiers) {
+            var name = parsePropertyName();
+            var questionToken = parseOptionalToken(55 /* QuestionToken */);
+            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
+                var method = createNode(150 /* MethodSignature */, fullStart);
+                method.modifiers = modifiers;
+                method.name = name;
+                method.questionToken = questionToken;
+                // Method signatures don't exist in expression contexts.  So they have neither
+                // [Yield] nor [Await]
+                fillSignature(56 /* ColonToken */, 4 /* Type */, method);
+                parseTypeMemberSemicolon();
+                return addJSDocComment(finishNode(method));
+            }
+            else {
+                var property = createNode(148 /* PropertySignature */, fullStart);
+                property.modifiers = modifiers;
+                property.name = name;
+                property.questionToken = questionToken;
+                property.type = parseTypeAnnotation();
+                if (token() === 58 /* EqualsToken */) {
+                    // Although type literal properties cannot not have initializers, we attempt
+                    // to parse an initializer so we can report in the checker that an interface
+                    // property or type literal property cannot have an initializer.
+                    property.initializer = parseNonParameterInitializer();
+                }
+                parseTypeMemberSemicolon();
+                return addJSDocComment(finishNode(property));
+            }
+        }
+        function isTypeMemberStart() {
+            // Return true if we have the start of a signature member
+            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
+                return true;
+            }
+            var idToken;
+            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier
+            while (ts.isModifierKind(token())) {
+                idToken = true;
+                nextToken();
+            }
+            // Index signatures and computed property names are type members
+            if (token() === 21 /* OpenBracketToken */) {
+                return true;
+            }
+            // Try to get the first property-like token following all modifiers
+            if (isLiteralPropertyName()) {
+                idToken = true;
+                nextToken();
+            }
+            // If we were able to get any potential identifier, check that it is
+            // the start of a member declaration
+            if (idToken) {
+                return token() === 19 /* OpenParenToken */ ||
+                    token() === 27 /* LessThanToken */ ||
+                    token() === 55 /* QuestionToken */ ||
+                    token() === 56 /* ColonToken */ ||
+                    token() === 26 /* CommaToken */ ||
+                    canParseSemicolon();
+            }
+            return false;
+        }
+        function parseTypeMember() {
+            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
+                return parseSignatureMember(155 /* CallSignature */);
+            }
+            if (token() === 94 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
+                return parseSignatureMember(156 /* ConstructSignature */);
+            }
+            var fullStart = getNodePos();
+            var modifiers = parseModifiers();
+            if (isIndexSignature()) {
+                return parseIndexSignatureDeclaration(fullStart, /*decorators*/ undefined, modifiers);
+            }
+            return parsePropertyOrMethodSignature(fullStart, modifiers);
+        }
+        function nextTokenIsOpenParenOrLessThan() {
+            nextToken();
+            return token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */;
+        }
+        function parseTypeLiteral() {
+            var node = createNode(163 /* TypeLiteral */);
+            node.members = parseObjectTypeMembers();
+            return finishNode(node);
+        }
+        function parseObjectTypeMembers() {
+            var members;
+            if (parseExpected(17 /* OpenBraceToken */)) {
+                members = parseList(4 /* TypeMembers */, parseTypeMember);
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                members = createMissingList();
+            }
+            return members;
+        }
+        function isStartOfMappedType() {
+            nextToken();
+            if (token() === 131 /* ReadonlyKeyword */) {
+                nextToken();
+            }
+            return token() === 21 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 92 /* InKeyword */;
+        }
+        function parseMappedTypeParameter() {
+            var node = createNode(145 /* TypeParameter */);
+            node.name = parseIdentifier();
+            parseExpected(92 /* InKeyword */);
+            node.constraint = parseType();
+            return finishNode(node);
+        }
+        function parseMappedType() {
+            var node = createNode(172 /* MappedType */);
+            parseExpected(17 /* OpenBraceToken */);
+            node.readonlyToken = parseOptionalToken(131 /* ReadonlyKeyword */);
+            parseExpected(21 /* OpenBracketToken */);
+            node.typeParameter = parseMappedTypeParameter();
+            parseExpected(22 /* CloseBracketToken */);
+            node.questionToken = parseOptionalToken(55 /* QuestionToken */);
+            node.type = parseTypeAnnotation();
+            parseSemicolon();
+            parseExpected(18 /* CloseBraceToken */);
+            return finishNode(node);
+        }
+        function parseTupleType() {
+            var node = createNode(165 /* TupleType */);
+            node.elementTypes = parseBracketedList(20 /* TupleElementTypes */, parseType, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */);
+            return finishNode(node);
+        }
+        function parseParenthesizedType() {
+            var node = createNode(168 /* ParenthesizedType */);
+            parseExpected(19 /* OpenParenToken */);
+            node.type = parseType();
+            parseExpected(20 /* CloseParenToken */);
+            return finishNode(node);
+        }
+        function parseFunctionOrConstructorType(kind) {
+            var node = createNode(kind);
+            if (kind === 161 /* ConstructorType */) {
+                parseExpected(94 /* NewKeyword */);
+            }
+            fillSignature(36 /* EqualsGreaterThanToken */, 4 /* Type */, node);
+            return addJSDocComment(finishNode(node));
+        }
+        function parseKeywordAndNoDot() {
+            var node = parseTokenNode();
+            return token() === 23 /* DotToken */ ? undefined : node;
+        }
+        function parseLiteralTypeNode(negative) {
+            var node = createNode(173 /* LiteralType */);
+            var unaryMinusExpression;
+            if (negative) {
+                unaryMinusExpression = createNode(192 /* PrefixUnaryExpression */);
+                unaryMinusExpression.operator = 38 /* MinusToken */;
+                nextToken();
+            }
+            var expression = token() === 101 /* TrueKeyword */ || token() === 86 /* FalseKeyword */
+                ? parseTokenNode()
+                : parseLiteralLikeNode(token());
+            if (negative) {
+                unaryMinusExpression.operand = expression;
+                finishNode(unaryMinusExpression);
+                expression = unaryMinusExpression;
+            }
+            node.literal = expression;
+            return finishNode(node);
+        }
+        function nextTokenIsNumericLiteral() {
+            return nextToken() === 8 /* NumericLiteral */;
+        }
+        function parseNonArrayType() {
+            switch (token()) {
+                case 119 /* AnyKeyword */:
+                case 136 /* StringKeyword */:
+                case 133 /* NumberKeyword */:
+                case 122 /* BooleanKeyword */:
+                case 137 /* SymbolKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 130 /* NeverKeyword */:
+                case 134 /* ObjectKeyword */:
+                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
+                    return tryParse(parseKeywordAndNoDot) || parseTypeReference();
+                case 39 /* AsteriskToken */:
+                    return parseJSDocAllType();
+                case 55 /* QuestionToken */:
+                    return parseJSDocUnknownOrNullableType();
+                case 89 /* FunctionKeyword */:
+                    return parseJSDocFunctionType();
+                case 24 /* DotDotDotToken */:
+                    return parseJSDocNodeWithType(274 /* JSDocVariadicType */);
+                case 51 /* ExclamationToken */:
+                    return parseJSDocNodeWithType(271 /* JSDocNonNullableType */);
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                case 9 /* StringLiteral */:
+                case 8 /* NumericLiteral */:
+                case 101 /* TrueKeyword */:
+                case 86 /* FalseKeyword */:
+                    return parseLiteralTypeNode();
+                case 38 /* MinusToken */:
+                    return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
+                case 105 /* VoidKeyword */:
+                case 95 /* NullKeyword */:
+                    return parseTokenNode();
+                case 99 /* ThisKeyword */: {
+                    var thisKeyword = parseThisTypeNode();
+                    if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
+                        return parseThisTypePredicate(thisKeyword);
+                    }
+                    else {
+                        return thisKeyword;
+                    }
+                }
+                case 103 /* TypeOfKeyword */:
+                    return parseTypeQuery();
+                case 17 /* OpenBraceToken */:
+                    return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
+                case 21 /* OpenBracketToken */:
+                    return parseTupleType();
+                case 19 /* OpenParenToken */:
+                    return parseParenthesizedType();
+                default:
+                    return parseTypeReference();
+            }
+        }
+        function isStartOfType(inStartOfParameter) {
+            switch (token()) {
+                case 119 /* AnyKeyword */:
+                case 136 /* StringKeyword */:
+                case 133 /* NumberKeyword */:
+                case 122 /* BooleanKeyword */:
+                case 137 /* SymbolKeyword */:
+                case 105 /* VoidKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 95 /* NullKeyword */:
+                case 99 /* ThisKeyword */:
+                case 103 /* TypeOfKeyword */:
+                case 130 /* NeverKeyword */:
+                case 17 /* OpenBraceToken */:
+                case 21 /* OpenBracketToken */:
+                case 27 /* LessThanToken */:
+                case 49 /* BarToken */:
+                case 48 /* AmpersandToken */:
+                case 94 /* NewKeyword */:
+                case 9 /* StringLiteral */:
+                case 8 /* NumericLiteral */:
+                case 101 /* TrueKeyword */:
+                case 86 /* FalseKeyword */:
+                case 134 /* ObjectKeyword */:
+                case 39 /* AsteriskToken */:
+                case 55 /* QuestionToken */:
+                case 51 /* ExclamationToken */:
+                case 24 /* DotDotDotToken */:
+                    return true;
+                case 38 /* MinusToken */:
+                    return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
+                case 19 /* OpenParenToken */:
+                    // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
+                    // or something that starts a type. We don't want to consider things like '(1)' a type.
+                    return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
+                default:
+                    return isIdentifier();
+            }
+        }
+        function isStartOfParenthesizedOrFunctionType() {
+            nextToken();
+            return token() === 20 /* CloseParenToken */ || isStartOfParameter() || isStartOfType();
+        }
+        function parsePostfixTypeOrHigher() {
+            var type = parseNonArrayType();
+            while (!scanner.hasPrecedingLineBreak()) {
+                switch (token()) {
+                    case 58 /* EqualsToken */:
+                        // only parse postfix = inside jsdoc, because it's ambiguous elsewhere
+                        if (!(contextFlags & 1048576 /* JSDoc */)) {
+                            return type;
+                        }
+                        type = createJSDocPostfixType(272 /* JSDocOptionalType */, type);
+                        break;
+                    case 51 /* ExclamationToken */:
+                        type = createJSDocPostfixType(271 /* JSDocNonNullableType */, type);
+                        break;
+                    case 55 /* QuestionToken */:
+                        type = createJSDocPostfixType(270 /* JSDocNullableType */, type);
+                        break;
+                    case 21 /* OpenBracketToken */:
+                        parseExpected(21 /* OpenBracketToken */);
+                        if (isStartOfType()) {
+                            var node = createNode(171 /* IndexedAccessType */, type.pos);
+                            node.objectType = type;
+                            node.indexType = parseType();
+                            parseExpected(22 /* CloseBracketToken */);
+                            type = finishNode(node);
+                        }
+                        else {
+                            var node = createNode(164 /* ArrayType */, type.pos);
+                            node.elementType = type;
+                            parseExpected(22 /* CloseBracketToken */);
+                            type = finishNode(node);
+                        }
+                        break;
+                    default:
+                        return type;
+                }
+            }
+            return type;
+        }
+        function createJSDocPostfixType(kind, type) {
+            nextToken();
+            var postfix = createNode(kind, type.pos);
+            postfix.type = type;
+            return finishNode(postfix);
+        }
+        function parseTypeOperator(operator) {
+            var node = createNode(170 /* TypeOperator */);
+            parseExpected(operator);
+            node.operator = operator;
+            node.type = parseTypeOperatorOrHigher();
+            return finishNode(node);
+        }
+        function parseTypeOperatorOrHigher() {
+            switch (token()) {
+                case 127 /* KeyOfKeyword */:
+                    return parseTypeOperator(127 /* KeyOfKeyword */);
+            }
+            return parsePostfixTypeOrHigher();
+        }
+        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
+            parseOptional(operator);
+            var type = parseConstituentType();
+            if (token() === operator) {
+                var types = [type];
+                while (parseOptional(operator)) {
+                    types.push(parseConstituentType());
+                }
+                var node = createNode(kind, type.pos);
+                node.types = createNodeArray(types, type.pos);
+                type = finishNode(node);
+            }
+            return type;
+        }
+        function parseIntersectionTypeOrHigher() {
+            return parseUnionOrIntersectionType(167 /* IntersectionType */, parseTypeOperatorOrHigher, 48 /* AmpersandToken */);
+        }
+        function parseUnionTypeOrHigher() {
+            return parseUnionOrIntersectionType(166 /* UnionType */, parseIntersectionTypeOrHigher, 49 /* BarToken */);
+        }
+        function isStartOfFunctionType() {
+            if (token() === 27 /* LessThanToken */) {
+                return true;
+            }
+            return token() === 19 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
+        }
+        function skipParameterStart() {
+            if (ts.isModifierKind(token())) {
+                // Skip modifiers
+                parseModifiers();
+            }
+            if (isIdentifier() || token() === 99 /* ThisKeyword */) {
+                nextToken();
+                return true;
+            }
+            if (token() === 21 /* OpenBracketToken */ || token() === 17 /* OpenBraceToken */) {
+                // Return true if we can parse an array or object binding pattern with no errors
+                var previousErrorCount = parseDiagnostics.length;
+                parseIdentifierOrPattern();
+                return previousErrorCount === parseDiagnostics.length;
+            }
+            return false;
+        }
+        function isUnambiguouslyStartOfFunctionType() {
+            nextToken();
+            if (token() === 20 /* CloseParenToken */ || token() === 24 /* DotDotDotToken */) {
+                // ( )
+                // ( ...
+                return true;
+            }
+            if (skipParameterStart()) {
+                // We successfully skipped modifiers (if any) and an identifier or binding pattern,
+                // now see if we have something that indicates a parameter declaration
+                if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ ||
+                    token() === 55 /* QuestionToken */ || token() === 58 /* EqualsToken */) {
+                    // ( xxx :
+                    // ( xxx ,
+                    // ( xxx ?
+                    // ( xxx =
+                    return true;
+                }
+                if (token() === 20 /* CloseParenToken */) {
+                    nextToken();
+                    if (token() === 36 /* EqualsGreaterThanToken */) {
+                        // ( xxx ) =>
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        function parseTypeOrTypePredicate() {
+            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
+            var type = parseType();
+            if (typePredicateVariable) {
+                var node = createNode(158 /* TypePredicate */, typePredicateVariable.pos);
+                node.parameterName = typePredicateVariable;
+                node.type = type;
+                return finishNode(node);
+            }
+            else {
+                return type;
+            }
+        }
+        function parseTypePredicatePrefix() {
+            var id = parseIdentifier();
+            if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
+                nextToken();
+                return id;
+            }
+        }
+        function parseType() {
+            // The rules about 'yield' only apply to actual code/expression contexts.  They don't
+            // apply to 'type' contexts.  So we disable these parameters here before moving on.
+            return doOutsideOfContext(20480 /* TypeExcludesFlags */, parseTypeWorker);
+        }
+        function parseTypeWorker() {
+            if (isStartOfFunctionType()) {
+                return parseFunctionOrConstructorType(160 /* FunctionType */);
+            }
+            if (token() === 94 /* NewKeyword */) {
+                return parseFunctionOrConstructorType(161 /* ConstructorType */);
+            }
+            return parseUnionTypeOrHigher();
+        }
+        function parseTypeAnnotation() {
+            return parseOptional(56 /* ColonToken */) ? parseType() : undefined;
+        }
+        // EXPRESSIONS
+        function isStartOfLeftHandSideExpression() {
+            switch (token()) {
+                case 99 /* ThisKeyword */:
+                case 97 /* SuperKeyword */:
+                case 95 /* NullKeyword */:
+                case 101 /* TrueKeyword */:
+                case 86 /* FalseKeyword */:
+                case 8 /* NumericLiteral */:
+                case 9 /* StringLiteral */:
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                case 14 /* TemplateHead */:
+                case 19 /* OpenParenToken */:
+                case 21 /* OpenBracketToken */:
+                case 17 /* OpenBraceToken */:
+                case 89 /* FunctionKeyword */:
+                case 75 /* ClassKeyword */:
+                case 94 /* NewKeyword */:
+                case 41 /* SlashToken */:
+                case 63 /* SlashEqualsToken */:
+                case 71 /* Identifier */:
+                    return true;
+                case 91 /* ImportKeyword */:
+                    return lookAhead(nextTokenIsOpenParenOrLessThan);
+                default:
+                    return isIdentifier();
+            }
+        }
+        function isStartOfExpression() {
+            if (isStartOfLeftHandSideExpression()) {
+                return true;
+            }
+            switch (token()) {
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 52 /* TildeToken */:
+                case 51 /* ExclamationToken */:
+                case 80 /* DeleteKeyword */:
+                case 103 /* TypeOfKeyword */:
+                case 105 /* VoidKeyword */:
+                case 43 /* PlusPlusToken */:
+                case 44 /* MinusMinusToken */:
+                case 27 /* LessThanToken */:
+                case 121 /* AwaitKeyword */:
+                case 116 /* YieldKeyword */:
+                    // Yield/await always starts an expression.  Either it is an identifier (in which case
+                    // it is definitely an expression).  Or it's a keyword (either because we're in
+                    // a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
+                    return true;
+                default:
+                    // Error tolerance.  If we see the start of some binary operator, we consider
+                    // that the start of an expression.  That way we'll parse out a missing identifier,
+                    // give a good message about an identifier being missing, and then consume the
+                    // rest of the binary expression.
+                    if (isBinaryOperator()) {
+                        return true;
+                    }
+                    return isIdentifier();
+            }
+        }
+        function isStartOfExpressionStatement() {
+            // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
+            return token() !== 17 /* OpenBraceToken */ &&
+                token() !== 89 /* FunctionKeyword */ &&
+                token() !== 75 /* ClassKeyword */ &&
+                token() !== 57 /* AtToken */ &&
+                isStartOfExpression();
+        }
+        function parseExpression() {
+            // Expression[in]:
+            //      AssignmentExpression[in]
+            //      Expression[in] , AssignmentExpression[in]
+            // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
+            var saveDecoratorContext = inDecoratorContext();
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ false);
+            }
+            var expr = parseAssignmentExpressionOrHigher();
+            var operatorToken;
+            while ((operatorToken = parseOptionalToken(26 /* CommaToken */))) {
+                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
+            }
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ true);
+            }
+            return expr;
+        }
+        function parseInitializer(inParameter, requireEqualsToken) {
+            if (token() !== 58 /* EqualsToken */) {
+                // It's not uncommon during typing for the user to miss writing the '=' token.  Check if
+                // there is no newline after the last token and if we're on an expression.  If so, parse
+                // this as an equals-value clause with a missing equals.
+                // NOTE: There are two places where we allow equals-value clauses.  The first is in a
+                // variable declarator.  The second is with a parameter.  For variable declarators
+                // it's more likely that a { would be a allowed (as an object literal).  While this
+                // is also allowed for parameters, the risk is that we consume the { as an object
+                // literal when it really will be for the block following the parameter.
+                if (scanner.hasPrecedingLineBreak() || (inParameter && token() === 17 /* OpenBraceToken */) || !isStartOfExpression()) {
+                    // preceding line break, open brace in a parameter (likely a function body) or current token is not an expression -
+                    // do not try to parse initializer
+                    return undefined;
+                }
+                if (inParameter && requireEqualsToken) {
+                    // = is required when speculatively parsing arrow function parameters,
+                    // so return a fake initializer as a signal that the equals token was missing
+                    var result = createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics._0_expected, "=");
+                    result.escapedText = "= not found";
+                    return result;
+                }
+            }
+            // Initializer[In, Yield] :
+            //     = AssignmentExpression[?In, ?Yield]
+            parseExpected(58 /* EqualsToken */);
+            return parseAssignmentExpressionOrHigher();
+        }
+        function parseAssignmentExpressionOrHigher() {
+            //  AssignmentExpression[in,yield]:
+            //      1) ConditionalExpression[?in,?yield]
+            //      2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
+            //      3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
+            //      4) ArrowFunctionExpression[?in,?yield]
+            //      5) AsyncArrowFunctionExpression[in,yield,await]
+            //      6) [+Yield] YieldExpression[?In]
+            //
+            // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
+            // (i.e. they're both BinaryExpressions with an assignment operator in it).
+            // First, do the simple check if we have a YieldExpression (production '6').
+            if (isYieldExpression()) {
+                return parseYieldExpression();
+            }
+            // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
+            // parameter list or is an async arrow function.
+            // AsyncArrowFunctionExpression:
+            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
+            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
+            // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
+            // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
+            //
+            // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
+            // not a  LeftHandSideExpression, nor does it start a ConditionalExpression.  So we are done
+            // with AssignmentExpression if we see one.
+            var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
+            if (arrowExpression) {
+                return arrowExpression;
+            }
+            // Now try to see if we're in production '1', '2' or '3'.  A conditional expression can
+            // start with a LogicalOrExpression, while the assignment productions can only start with
+            // LeftHandSideExpressions.
+            //
+            // So, first, we try to just parse out a BinaryExpression.  If we get something that is a
+            // LeftHandSide or higher, then we can try to parse out the assignment expression part.
+            // Otherwise, we try to parse out the conditional expression bit.  We want to allow any
+            // binary expression here, so we pass in the 'lowest' precedence here so that it matches
+            // and consumes anything.
+            var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
+            // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
+            // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
+            // identifier and the current token is an arrow.
+            if (expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) {
+                return parseSimpleArrowFunctionExpression(expr);
+            }
+            // Now see if we might be in cases '2' or '3'.
+            // If the expression was a LHS expression, and we have an assignment operator, then
+            // we're in '2' or '3'. Consume the assignment and return.
+            //
+            // Note: we call reScanGreaterToken so that we get an appropriately merged token
+            // for cases like > > =  becoming >>=
+            if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
+                return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
+            }
+            // It wasn't an assignment or a lambda.  This is a conditional expression:
+            return parseConditionalExpressionRest(expr);
+        }
+        function isYieldExpression() {
+            if (token() === 116 /* YieldKeyword */) {
+                // If we have a 'yield' keyword, and this is a context where yield expressions are
+                // allowed, then definitely parse out a yield expression.
+                if (inYieldContext()) {
+                    return true;
+                }
+                // We're in a context where 'yield expr' is not allowed.  However, if we can
+                // definitely tell that the user was trying to parse a 'yield expr' and not
+                // just a normal expr that start with a 'yield' identifier, then parse out
+                // a 'yield expr'.  We can then report an error later that they are only
+                // allowed in generator expressions.
+                //
+                // for example, if we see 'yield(foo)', then we'll have to treat that as an
+                // invocation expression of something called 'yield'.  However, if we have
+                // 'yield foo' then that is not legal as a normal expression, so we can
+                // definitely recognize this as a yield expression.
+                //
+                // for now we just check if the next token is an identifier.  More heuristics
+                // can be added here later as necessary.  We just need to make sure that we
+                // don't accidentally consume something legal.
+                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
+            }
+            return false;
+        }
+        function nextTokenIsIdentifierOnSameLine() {
+            nextToken();
+            return !scanner.hasPrecedingLineBreak() && isIdentifier();
+        }
+        function parseYieldExpression() {
+            var node = createNode(197 /* YieldExpression */);
+            // YieldExpression[In] :
+            //      yield
+            //      yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
+            //      yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
+            nextToken();
+            if (!scanner.hasPrecedingLineBreak() &&
+                (token() === 39 /* AsteriskToken */ || isStartOfExpression())) {
+                node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
+                node.expression = parseAssignmentExpressionOrHigher();
+                return finishNode(node);
+            }
+            else {
+                // if the next token is not on the same line as yield.  or we don't have an '*' or
+                // the start of an expression, then this is just a simple "yield" expression.
+                return finishNode(node);
+            }
+        }
+        function parseSimpleArrowFunctionExpression(identifier, asyncModifier) {
+            ts.Debug.assert(token() === 36 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
+            var node;
+            if (asyncModifier) {
+                node = createNode(187 /* ArrowFunction */, asyncModifier.pos);
+                node.modifiers = asyncModifier;
+            }
+            else {
+                node = createNode(187 /* ArrowFunction */, identifier.pos);
+            }
+            var parameter = createNode(146 /* Parameter */, identifier.pos);
+            parameter.name = identifier;
+            finishNode(parameter);
+            node.parameters = createNodeArray([parameter], parameter.pos, parameter.end);
+            node.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
+            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
+            return addJSDocComment(finishNode(node));
+        }
+        function tryParseParenthesizedArrowFunctionExpression() {
+            var triState = isParenthesizedArrowFunctionExpression();
+            if (triState === 0 /* False */) {
+                // It's definitely not a parenthesized arrow function expression.
+                return undefined;
+            }
+            // If we definitely have an arrow function, then we can just parse one, not requiring a
+            // following => or { token. Otherwise, we *might* have an arrow function.  Try to parse
+            // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
+            // expression instead.
+            var arrowFunction = triState === 1 /* True */
+                ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true)
+                : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
+            if (!arrowFunction) {
+                // Didn't appear to actually be a parenthesized arrow function.  Just bail out.
+                return undefined;
+            }
+            var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */);
+            // If we have an arrow, then try to parse the body. Even if not, try to parse if we
+            // have an opening brace, just in case we're in an error state.
+            var lastToken = token();
+            arrowFunction.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
+            arrowFunction.body = (lastToken === 36 /* EqualsGreaterThanToken */ || lastToken === 17 /* OpenBraceToken */)
+                ? parseArrowFunctionExpressionBody(isAsync)
+                : parseIdentifier();
+            return addJSDocComment(finishNode(arrowFunction));
+        }
+        //  True        -> We definitely expect a parenthesized arrow function here.
+        //  False       -> There *cannot* be a parenthesized arrow function here.
+        //  Unknown     -> There *might* be a parenthesized arrow function here.
+        //                 Speculatively look ahead to be sure, and rollback if not.
+        function isParenthesizedArrowFunctionExpression() {
+            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */ || token() === 120 /* AsyncKeyword */) {
+                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
+            }
+            if (token() === 36 /* EqualsGreaterThanToken */) {
+                // ERROR RECOVERY TWEAK:
+                // If we see a standalone => try to parse it as an arrow function expression as that's
+                // likely what the user intended to write.
+                return 1 /* True */;
+            }
+            // Definitely not a parenthesized arrow function.
+            return 0 /* False */;
+        }
+        function isParenthesizedArrowFunctionExpressionWorker() {
+            if (token() === 120 /* AsyncKeyword */) {
+                nextToken();
+                if (scanner.hasPrecedingLineBreak()) {
+                    return 0 /* False */;
+                }
+                if (token() !== 19 /* OpenParenToken */ && token() !== 27 /* LessThanToken */) {
+                    return 0 /* False */;
+                }
+            }
+            var first = token();
+            var second = nextToken();
+            if (first === 19 /* OpenParenToken */) {
+                if (second === 20 /* CloseParenToken */) {
+                    // Simple cases: "() =>", "(): ", and  "() {".
+                    // This is an arrow function with no parameters.
+                    // The last one is not actually an arrow function,
+                    // but this is probably what the user intended.
+                    var third = nextToken();
+                    switch (third) {
+                        case 36 /* EqualsGreaterThanToken */:
+                        case 56 /* ColonToken */:
+                        case 17 /* OpenBraceToken */:
+                            return 1 /* True */;
+                        default:
+                            return 0 /* False */;
+                    }
+                }
+                // If encounter "([" or "({", this could be the start of a binding pattern.
+                // Examples:
+                //      ([ x ]) => { }
+                //      ({ x }) => { }
+                //      ([ x ])
+                //      ({ x })
+                if (second === 21 /* OpenBracketToken */ || second === 17 /* OpenBraceToken */) {
+                    return 2 /* Unknown */;
+                }
+                // Simple case: "(..."
+                // This is an arrow function with a rest parameter.
+                if (second === 24 /* DotDotDotToken */) {
+                    return 1 /* True */;
+                }
+                // If we had "(" followed by something that's not an identifier,
+                // then this definitely doesn't look like a lambda.
+                // Note: we could be a little more lenient and allow
+                // "(public" or "(private". These would not ever actually be allowed,
+                // but we could provide a good error message instead of bailing out.
+                if (!isIdentifier()) {
+                    return 0 /* False */;
+                }
+                // If we have something like "(a:", then we must have a
+                // type-annotated parameter in an arrow function expression.
+                if (nextToken() === 56 /* ColonToken */) {
+                    return 1 /* True */;
+                }
+                // This *could* be a parenthesized arrow function.
+                // Return Unknown to let the caller know.
+                return 2 /* Unknown */;
+            }
+            else {
+                ts.Debug.assert(first === 27 /* LessThanToken */);
+                // If we have "<" not followed by an identifier,
+                // then this definitely is not an arrow function.
+                if (!isIdentifier()) {
+                    return 0 /* False */;
+                }
+                // JSX overrides
+                if (sourceFile.languageVariant === 1 /* JSX */) {
+                    var isArrowFunctionInJsx = lookAhead(function () {
+                        var third = nextToken();
+                        if (third === 85 /* ExtendsKeyword */) {
+                            var fourth = nextToken();
+                            switch (fourth) {
+                                case 58 /* EqualsToken */:
+                                case 29 /* GreaterThanToken */:
+                                    return false;
+                                default:
+                                    return true;
+                            }
+                        }
+                        else if (third === 26 /* CommaToken */) {
+                            return true;
+                        }
+                        return false;
+                    });
+                    if (isArrowFunctionInJsx) {
+                        return 1 /* True */;
+                    }
+                    return 0 /* False */;
+                }
+                // This *could* be a parenthesized arrow function.
+                return 2 /* Unknown */;
+            }
+        }
+        function parsePossibleParenthesizedArrowFunctionExpressionHead() {
+            return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
+        }
+        function tryParseAsyncSimpleArrowFunctionExpression() {
+            // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
+            if (token() === 120 /* AsyncKeyword */) {
+                if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
+                    var asyncModifier = parseModifiersForArrowFunction();
+                    var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
+                    return parseSimpleArrowFunctionExpression(expr, asyncModifier);
+                }
+            }
+            return undefined;
+        }
+        function isUnParenthesizedAsyncArrowFunctionWorker() {
+            // AsyncArrowFunctionExpression:
+            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
+            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
+            if (token() === 120 /* AsyncKeyword */) {
+                nextToken();
+                // If the "async" is followed by "=>" token then it is not a begining of an async arrow-function
+                // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
+                if (scanner.hasPrecedingLineBreak() || token() === 36 /* EqualsGreaterThanToken */) {
+                    return 0 /* False */;
+                }
+                // Check for un-parenthesized AsyncArrowFunction
+                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
+                if (!scanner.hasPrecedingLineBreak() && expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) {
+                    return 1 /* True */;
+                }
+            }
+            return 0 /* False */;
+        }
+        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
+            var node = createNode(187 /* ArrowFunction */);
+            node.modifiers = parseModifiersForArrowFunction();
+            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
+            // Arrow functions are never generators.
+            //
+            // If we're speculatively parsing a signature for a parenthesized arrow function, then
+            // we have to have a complete parameter list.  Otherwise we might see something like
+            // a => (b => c)
+            // And think that "(b =>" was actually a parenthesized arrow function with a missing
+            // close paren.
+            fillSignature(56 /* ColonToken */, isAsync | (allowAmbiguity ? 0 /* None */ : 8 /* RequireCompleteParameterList */), node);
+            // If we couldn't get parameters, we definitely could not parse out an arrow function.
+            if (!node.parameters) {
+                return undefined;
+            }
+            // Parsing a signature isn't enough.
+            // Parenthesized arrow signatures often look like other valid expressions.
+            // For instance:
+            //  - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
+            //  - "(x,y)" is a comma expression parsed as a signature with two parameters.
+            //  - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
+            //
+            // So we need just a bit of lookahead to ensure that it can only be a signature.
+            if (!allowAmbiguity && ((token() !== 36 /* EqualsGreaterThanToken */ && token() !== 17 /* OpenBraceToken */) ||
+                ts.find(node.parameters, function (p) { return p.initializer && ts.isIdentifier(p.initializer) && p.initializer.escapedText === "= not found"; }))) {
+                // Returning undefined here will cause our caller to rewind to where we started from.
+                return undefined;
+            }
+            return node;
+        }
+        function parseArrowFunctionExpressionBody(isAsync) {
+            if (token() === 17 /* OpenBraceToken */) {
+                return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
+            }
+            if (token() !== 25 /* SemicolonToken */ &&
+                token() !== 89 /* FunctionKeyword */ &&
+                token() !== 75 /* ClassKeyword */ &&
+                isStartOfStatement() &&
+                !isStartOfExpressionStatement()) {
+                // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
+                //
+                // Here we try to recover from a potential error situation in the case where the
+                // user meant to supply a block. For example, if the user wrote:
+                //
+                //  a =>
+                //      let v = 0;
+                //  }
+                //
+                // they may be missing an open brace.  Check to see if that's the case so we can
+                // try to recover better.  If we don't do this, then the next close curly we see may end
+                // up preemptively closing the containing construct.
+                //
+                // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error.
+                return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */));
+            }
+            return isAsync
+                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
+                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
+        }
+        function parseConditionalExpressionRest(leftOperand) {
+            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
+            var questionToken = parseOptionalToken(55 /* QuestionToken */);
+            if (!questionToken) {
+                return leftOperand;
+            }
+            // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
+            // we do not that for the 'whenFalse' part.
+            var node = createNode(195 /* ConditionalExpression */, leftOperand.pos);
+            node.condition = leftOperand;
+            node.questionToken = questionToken;
+            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
+            node.colonToken = parseExpectedToken(56 /* ColonToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */));
+            node.whenFalse = parseAssignmentExpressionOrHigher();
+            return finishNode(node);
+        }
+        function parseBinaryExpressionOrHigher(precedence) {
+            var leftOperand = parseUnaryExpressionOrHigher();
+            return parseBinaryExpressionRest(precedence, leftOperand);
+        }
+        function isInOrOfKeyword(t) {
+            return t === 92 /* InKeyword */ || t === 142 /* OfKeyword */;
+        }
+        function parseBinaryExpressionRest(precedence, leftOperand) {
+            while (true) {
+                // We either have a binary operator here, or we're finished.  We call
+                // reScanGreaterToken so that we merge token sequences like > and = into >=
+                reScanGreaterToken();
+                var newPrecedence = getBinaryOperatorPrecedence();
+                // Check the precedence to see if we should "take" this operator
+                // - For left associative operator (all operator but **), consume the operator,
+                //   recursively call the function below, and parse binaryExpression as a rightOperand
+                //   of the caller if the new precedence of the operator is greater then or equal to the current precedence.
+                //   For example:
+                //      a - b - c;
+                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
+                //      a * b - c
+                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
+                //      a - b * c;
+                //            ^token; leftOperand = b. Return b * c to the caller as a rightOperand
+                // - For right associative operator (**), consume the operator, recursively call the function
+                //   and parse binaryExpression as a rightOperand of the caller if the new precedence of
+                //   the operator is strictly grater than the current precedence
+                //   For example:
+                //      a ** b ** c;
+                //             ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+                //      a - b ** c;
+                //            ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+                //      a ** b - c
+                //             ^token; leftOperand = b. Return b to the caller as a rightOperand
+                var consumeCurrentOperator = token() === 40 /* AsteriskAsteriskToken */ ?
+                    newPrecedence >= precedence :
+                    newPrecedence > precedence;
+                if (!consumeCurrentOperator) {
+                    break;
+                }
+                if (token() === 92 /* InKeyword */ && inDisallowInContext()) {
+                    break;
+                }
+                if (token() === 118 /* AsKeyword */) {
+                    // Make sure we *do* perform ASI for constructs like this:
+                    //    var x = foo
+                    //    as (Bar)
+                    // This should be parsed as an initialized variable, followed
+                    // by a function call to 'as' with the argument 'Bar'
+                    if (scanner.hasPrecedingLineBreak()) {
+                        break;
+                    }
+                    else {
+                        nextToken();
+                        leftOperand = makeAsExpression(leftOperand, parseType());
+                    }
+                }
+                else {
+                    leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+                }
+            }
+            return leftOperand;
+        }
+        function isBinaryOperator() {
+            if (inDisallowInContext() && token() === 92 /* InKeyword */) {
+                return false;
+            }
+            return getBinaryOperatorPrecedence() > 0;
+        }
+        function getBinaryOperatorPrecedence() {
+            switch (token()) {
+                case 54 /* BarBarToken */:
+                    return 1;
+                case 53 /* AmpersandAmpersandToken */:
+                    return 2;
+                case 49 /* BarToken */:
+                    return 3;
+                case 50 /* CaretToken */:
+                    return 4;
+                case 48 /* AmpersandToken */:
+                    return 5;
+                case 32 /* EqualsEqualsToken */:
+                case 33 /* ExclamationEqualsToken */:
+                case 34 /* EqualsEqualsEqualsToken */:
+                case 35 /* ExclamationEqualsEqualsToken */:
+                    return 6;
+                case 27 /* LessThanToken */:
+                case 29 /* GreaterThanToken */:
+                case 30 /* LessThanEqualsToken */:
+                case 31 /* GreaterThanEqualsToken */:
+                case 93 /* InstanceOfKeyword */:
+                case 92 /* InKeyword */:
+                case 118 /* AsKeyword */:
+                    return 7;
+                case 45 /* LessThanLessThanToken */:
+                case 46 /* GreaterThanGreaterThanToken */:
+                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                    return 8;
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                    return 9;
+                case 39 /* AsteriskToken */:
+                case 41 /* SlashToken */:
+                case 42 /* PercentToken */:
+                    return 10;
+                case 40 /* AsteriskAsteriskToken */:
+                    return 11;
+            }
+            // -1 is lower than all other precedences.  Returning it will cause binary expression
+            // parsing to stop.
+            return -1;
+        }
+        function makeBinaryExpression(left, operatorToken, right) {
+            var node = createNode(194 /* BinaryExpression */, left.pos);
+            node.left = left;
+            node.operatorToken = operatorToken;
+            node.right = right;
+            return finishNode(node);
+        }
+        function makeAsExpression(left, right) {
+            var node = createNode(202 /* AsExpression */, left.pos);
+            node.expression = left;
+            node.type = right;
+            return finishNode(node);
+        }
+        function parsePrefixUnaryExpression() {
+            var node = createNode(192 /* PrefixUnaryExpression */);
+            node.operator = token();
+            nextToken();
+            node.operand = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        function parseDeleteExpression() {
+            var node = createNode(188 /* DeleteExpression */);
+            nextToken();
+            node.expression = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        function parseTypeOfExpression() {
+            var node = createNode(189 /* TypeOfExpression */);
+            nextToken();
+            node.expression = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        function parseVoidExpression() {
+            var node = createNode(190 /* VoidExpression */);
+            nextToken();
+            node.expression = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        function isAwaitExpression() {
+            if (token() === 121 /* AwaitKeyword */) {
+                if (inAwaitContext()) {
+                    return true;
+                }
+                // here we are using similar heuristics as 'isYieldExpression'
+                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
+            }
+            return false;
+        }
+        function parseAwaitExpression() {
+            var node = createNode(191 /* AwaitExpression */);
+            nextToken();
+            node.expression = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        /**
+         * Parse ES7 exponential expression and await expression
+         *
+         * ES7 ExponentiationExpression:
+         *      1) UnaryExpression[?Yield]
+         *      2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
+         *
+         */
+        function parseUnaryExpressionOrHigher() {
+            /**
+             * ES7 UpdateExpression:
+             *      1) LeftHandSideExpression[?Yield]
+             *      2) LeftHandSideExpression[?Yield][no LineTerminator here]++
+             *      3) LeftHandSideExpression[?Yield][no LineTerminator here]--
+             *      4) ++UnaryExpression[?Yield]
+             *      5) --UnaryExpression[?Yield]
+             */
+            if (isUpdateExpression()) {
+                var updateExpression = parseUpdateExpression();
+                return token() === 40 /* AsteriskAsteriskToken */ ?
+                    parseBinaryExpressionRest(getBinaryOperatorPrecedence(), updateExpression) :
+                    updateExpression;
+            }
+            /**
+             * ES7 UnaryExpression:
+             *      1) UpdateExpression[?yield]
+             *      2) delete UpdateExpression[?yield]
+             *      3) void UpdateExpression[?yield]
+             *      4) typeof UpdateExpression[?yield]
+             *      5) + UpdateExpression[?yield]
+             *      6) - UpdateExpression[?yield]
+             *      7) ~ UpdateExpression[?yield]
+             *      8) ! UpdateExpression[?yield]
+             */
+            var unaryOperator = token();
+            var simpleUnaryExpression = parseSimpleUnaryExpression();
+            if (token() === 40 /* AsteriskAsteriskToken */) {
+                var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
+                if (simpleUnaryExpression.kind === 184 /* TypeAssertionExpression */) {
+                    parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
+                }
+                else {
+                    parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
+                }
+            }
+            return simpleUnaryExpression;
+        }
+        /**
+         * Parse ES7 simple-unary expression or higher:
+         *
+         * ES7 UnaryExpression:
+         *      1) UpdateExpression[?yield]
+         *      2) delete UnaryExpression[?yield]
+         *      3) void UnaryExpression[?yield]
+         *      4) typeof UnaryExpression[?yield]
+         *      5) + UnaryExpression[?yield]
+         *      6) - UnaryExpression[?yield]
+         *      7) ~ UnaryExpression[?yield]
+         *      8) ! UnaryExpression[?yield]
+         *      9) [+Await] await UnaryExpression[?yield]
+         */
+        function parseSimpleUnaryExpression() {
+            switch (token()) {
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 52 /* TildeToken */:
+                case 51 /* ExclamationToken */:
+                    return parsePrefixUnaryExpression();
+                case 80 /* DeleteKeyword */:
+                    return parseDeleteExpression();
+                case 103 /* TypeOfKeyword */:
+                    return parseTypeOfExpression();
+                case 105 /* VoidKeyword */:
+                    return parseVoidExpression();
+                case 27 /* LessThanToken */:
+                    // This is modified UnaryExpression grammar in TypeScript
+                    //  UnaryExpression (modified):
+                    //      < type > UnaryExpression
+                    return parseTypeAssertion();
+                case 121 /* AwaitKeyword */:
+                    if (isAwaitExpression()) {
+                        return parseAwaitExpression();
+                    }
+                // falls through
+                default:
+                    return parseUpdateExpression();
+            }
+        }
+        /**
+         * Check if the current token can possibly be an ES7 increment expression.
+         *
+         * ES7 UpdateExpression:
+         *      LeftHandSideExpression[?Yield]
+         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
+         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
+         *      ++LeftHandSideExpression[?Yield]
+         *      --LeftHandSideExpression[?Yield]
+         */
+        function isUpdateExpression() {
+            // This function is called inside parseUnaryExpression to decide
+            // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
+            switch (token()) {
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 52 /* TildeToken */:
+                case 51 /* ExclamationToken */:
+                case 80 /* DeleteKeyword */:
+                case 103 /* TypeOfKeyword */:
+                case 105 /* VoidKeyword */:
+                case 121 /* AwaitKeyword */:
+                    return false;
+                case 27 /* LessThanToken */:
+                    // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
+                    if (sourceFile.languageVariant !== 1 /* JSX */) {
+                        return false;
+                    }
+                // We are in JSX context and the token is part of JSXElement.
+                // falls through
+                default:
+                    return true;
+            }
+        }
+        /**
+         * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
+         *
+         * ES7 UpdateExpression[yield]:
+         *      1) LeftHandSideExpression[?yield]
+         *      2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
+         *      3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
+         *      4) ++LeftHandSideExpression[?yield]
+         *      5) --LeftHandSideExpression[?yield]
+         * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
+         */
+        function parseUpdateExpression() {
+            if (token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) {
+                var node = createNode(192 /* PrefixUnaryExpression */);
+                node.operator = token();
+                nextToken();
+                node.operand = parseLeftHandSideExpressionOrHigher();
+                return finishNode(node);
+            }
+            else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
+                // JSXElement is part of primaryExpression
+                return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
+            }
+            var expression = parseLeftHandSideExpressionOrHigher();
+            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
+            if ((token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
+                var node = createNode(193 /* PostfixUnaryExpression */, expression.pos);
+                node.operand = expression;
+                node.operator = token();
+                nextToken();
+                return finishNode(node);
+            }
+            return expression;
+        }
+        function parseLeftHandSideExpressionOrHigher() {
+            // Original Ecma:
+            // LeftHandSideExpression: See 11.2
+            //      NewExpression
+            //      CallExpression
+            //
+            // Our simplification:
+            //
+            // LeftHandSideExpression: See 11.2
+            //      MemberExpression
+            //      CallExpression
+            //
+            // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
+            // MemberExpression to make our lives easier.
+            //
+            // to best understand the below code, it's important to see how CallExpression expands
+            // out into its own productions:
+            //
+            // CallExpression:
+            //      MemberExpression Arguments
+            //      CallExpression Arguments
+            //      CallExpression[Expression]
+            //      CallExpression.IdentifierName
+            //      import (AssignmentExpression)
+            //      super Arguments
+            //      super.IdentifierName
+            //
+            // Because of the recursion in these calls, we need to bottom out first. There are three
+            // bottom out states we can run into: 1) We see 'super' which must start either of
+            // the last two CallExpression productions. 2) We see 'import' which must start import call.
+            // 3)we have a MemberExpression which either completes the LeftHandSideExpression,
+            // or starts the beginning of the first four CallExpression productions.
+            var expression;
+            if (token() === 91 /* ImportKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
+                // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
+                // For example:
+                //      var foo3 = require("subfolder
+                //      import * as foo1 from "module-from-node  -> we want this import to be a statement rather than import call expression
+                sourceFile.flags |= 524288 /* PossiblyContainsDynamicImport */;
+                expression = parseTokenNode();
+            }
+            else {
+                expression = token() === 97 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher();
+            }
+            // Now, we *may* be complete.  However, we might have consumed the start of a
+            // CallExpression.  As such, we need to consume the rest of it here to be complete.
+            return parseCallExpressionRest(expression);
+        }
+        function parseMemberExpressionOrHigher() {
+            // Note: to make our lives simpler, we decompose the NewExpression productions and
+            // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
+            // like so:
+            //
+            //   PrimaryExpression : See 11.1
+            //      this
+            //      Identifier
+            //      Literal
+            //      ArrayLiteral
+            //      ObjectLiteral
+            //      (Expression)
+            //      FunctionExpression
+            //      new MemberExpression Arguments?
+            //
+            //   MemberExpression : See 11.2
+            //      PrimaryExpression
+            //      MemberExpression[Expression]
+            //      MemberExpression.IdentifierName
+            //
+            //   CallExpression : See 11.2
+            //      MemberExpression
+            //      CallExpression Arguments
+            //      CallExpression[Expression]
+            //      CallExpression.IdentifierName
+            //
+            // Technically this is ambiguous.  i.e. CallExpression defines:
+            //
+            //   CallExpression:
+            //      CallExpression Arguments
+            //
+            // If you see: "new Foo()"
+            //
+            // Then that could be treated as a single ObjectCreationExpression, or it could be
+            // treated as the invocation of "new Foo".  We disambiguate that in code (to match
+            // the original grammar) by making sure that if we see an ObjectCreationExpression
+            // we always consume arguments if they are there. So we treat "new Foo()" as an
+            // object creation only, and not at all as an invocation)  Another way to think
+            // about this is that for every "new" that we see, we will consume an argument list if
+            // it is there as part of the *associated* object creation node.  Any additional
+            // argument lists we see, will become invocation expressions.
+            //
+            // Because there are no other places in the grammar now that refer to FunctionExpression
+            // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
+            // production.
+            //
+            // Because CallExpression and MemberExpression are left recursive, we need to bottom out
+            // of the recursion immediately.  So we parse out a primary expression to start with.
+            var expression = parsePrimaryExpression();
+            return parseMemberExpressionRest(expression);
+        }
+        function parseSuperExpression() {
+            var expression = parseTokenNode();
+            if (token() === 19 /* OpenParenToken */ || token() === 23 /* DotToken */ || token() === 21 /* OpenBracketToken */) {
+                return expression;
+            }
+            // If we have seen "super" it must be followed by '(' or '.'.
+            // If it wasn't then just try to parse out a '.' and report an error.
+            var node = createNode(179 /* PropertyAccessExpression */, expression.pos);
+            node.expression = expression;
+            parseExpectedToken(23 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
+            node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+            return finishNode(node);
+        }
+        function tagNamesAreEquivalent(lhs, rhs) {
+            if (lhs.kind !== rhs.kind) {
+                return false;
+            }
+            if (lhs.kind === 71 /* Identifier */) {
+                return lhs.escapedText === rhs.escapedText;
+            }
+            if (lhs.kind === 99 /* ThisKeyword */) {
+                return true;
+            }
+            // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
+            // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
+            // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
+            return lhs.name.escapedText === rhs.name.escapedText &&
+                tagNamesAreEquivalent(lhs.expression, rhs.expression);
+        }
+        function parseJsxElementOrSelfClosingElement(inExpressionContext) {
+            var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
+            var result;
+            if (opening.kind === 251 /* JsxOpeningElement */) {
+                var node = createNode(249 /* JsxElement */, opening.pos);
+                node.openingElement = opening;
+                node.children = parseJsxChildren(node.openingElement.tagName);
+                node.closingElement = parseJsxClosingElement(inExpressionContext);
+                if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
+                    parseErrorAtPosition(node.closingElement.pos, node.closingElement.end - node.closingElement.pos, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName));
+                }
+                result = finishNode(node);
+            }
+            else {
+                ts.Debug.assert(opening.kind === 250 /* JsxSelfClosingElement */);
+                // Nothing else to do for self-closing elements
+                result = opening;
+            }
+            // If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
+            // an enclosing tag), we'll naively try to parse   ^ this as a 'less than' operator and the remainder of the tag
+            // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
+            // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
+            // does less damage and we can report a better error.
+            // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
+            // of one sort or another.
+            if (inExpressionContext && token() === 27 /* LessThanToken */) {
+                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
+                if (invalidElement) {
+                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
+                    var badNode = createNode(194 /* BinaryExpression */, result.pos);
+                    badNode.end = invalidElement.end;
+                    badNode.left = result;
+                    badNode.right = invalidElement;
+                    badNode.operatorToken = createMissingNode(26 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
+                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
+                    return badNode;
+                }
+            }
+            return result;
+        }
+        function parseJsxText() {
+            var node = createNode(10 /* JsxText */, scanner.getStartPos());
+            node.containsOnlyWhiteSpaces = currentToken === 11 /* JsxTextAllWhiteSpaces */;
+            currentToken = scanner.scanJsxToken();
+            return finishNode(node);
+        }
+        function parseJsxChild() {
+            switch (token()) {
+                case 10 /* JsxText */:
+                case 11 /* JsxTextAllWhiteSpaces */:
+                    return parseJsxText();
+                case 17 /* OpenBraceToken */:
+                    return parseJsxExpression(/*inExpressionContext*/ false);
+                case 27 /* LessThanToken */:
+                    return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
+            }
+            ts.Debug.fail("Unknown JSX child kind " + token());
+        }
+        function parseJsxChildren(openingTagName) {
+            var list = [];
+            var listPos = getNodePos();
+            var saveParsingContext = parsingContext;
+            parsingContext |= 1 << 14 /* JsxChildren */;
+            while (true) {
+                currentToken = scanner.reScanJsxToken();
+                if (token() === 28 /* LessThanSlashToken */) {
+                    // Closing tag
+                    break;
+                }
+                else if (token() === 1 /* EndOfFileToken */) {
+                    // If we hit EOF, issue the error at the tag that lacks the closing element
+                    // rather than at the end of the file (which is useless)
+                    parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
+                    break;
+                }
+                else if (token() === 7 /* ConflictMarkerTrivia */) {
+                    break;
+                }
+                var child = parseJsxChild();
+                if (child) {
+                    list.push(child);
+                }
+            }
+            parsingContext = saveParsingContext;
+            return createNodeArray(list, listPos);
+        }
+        function parseJsxAttributes() {
+            var jsxAttributes = createNode(254 /* JsxAttributes */);
+            jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute);
+            return finishNode(jsxAttributes);
+        }
+        function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
+            var fullStart = scanner.getStartPos();
+            parseExpected(27 /* LessThanToken */);
+            var tagName = parseJsxElementName();
+            var attributes = parseJsxAttributes();
+            var node;
+            if (token() === 29 /* GreaterThanToken */) {
+                // Closing tag, so scan the immediately-following text with the JSX scanning instead
+                // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
+                // scanning errors
+                node = createNode(251 /* JsxOpeningElement */, fullStart);
+                scanJsxText();
+            }
+            else {
+                parseExpected(41 /* SlashToken */);
+                if (inExpressionContext) {
+                    parseExpected(29 /* GreaterThanToken */);
+                }
+                else {
+                    parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
+                    scanJsxText();
+                }
+                node = createNode(250 /* JsxSelfClosingElement */, fullStart);
+            }
+            node.tagName = tagName;
+            node.attributes = attributes;
+            return finishNode(node);
+        }
+        function parseJsxElementName() {
+            scanJsxIdentifier();
+            // JsxElement can have name in the form of
+            //      propertyAccessExpression
+            //      primaryExpression in the form of an identifier and "this" keyword
+            // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
+            // We only want to consider "this" as a primaryExpression
+            var expression = token() === 99 /* ThisKeyword */ ?
+                parseTokenNode() : parseIdentifierName();
+            while (parseOptional(23 /* DotToken */)) {
+                var propertyAccess = createNode(179 /* PropertyAccessExpression */, expression.pos);
+                propertyAccess.expression = expression;
+                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+                expression = finishNode(propertyAccess);
+            }
+            return expression;
+        }
+        function parseJsxExpression(inExpressionContext) {
+            var node = createNode(256 /* JsxExpression */);
+            parseExpected(17 /* OpenBraceToken */);
+            if (token() !== 18 /* CloseBraceToken */) {
+                node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
+                node.expression = parseAssignmentExpressionOrHigher();
+            }
+            if (inExpressionContext) {
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                parseExpected(18 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false);
+                scanJsxText();
+            }
+            return finishNode(node);
+        }
+        function parseJsxAttribute() {
+            if (token() === 17 /* OpenBraceToken */) {
+                return parseJsxSpreadAttribute();
+            }
+            scanJsxIdentifier();
+            var node = createNode(253 /* JsxAttribute */);
+            node.name = parseIdentifierName();
+            if (token() === 58 /* EqualsToken */) {
+                switch (scanJsxAttributeValue()) {
+                    case 9 /* StringLiteral */:
+                        node.initializer = parseLiteralNode();
+                        break;
+                    default:
+                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
+                        break;
+                }
+            }
+            return finishNode(node);
+        }
+        function parseJsxSpreadAttribute() {
+            var node = createNode(255 /* JsxSpreadAttribute */);
+            parseExpected(17 /* OpenBraceToken */);
+            parseExpected(24 /* DotDotDotToken */);
+            node.expression = parseExpression();
+            parseExpected(18 /* CloseBraceToken */);
+            return finishNode(node);
+        }
+        function parseJsxClosingElement(inExpressionContext) {
+            var node = createNode(252 /* JsxClosingElement */);
+            parseExpected(28 /* LessThanSlashToken */);
+            node.tagName = parseJsxElementName();
+            if (inExpressionContext) {
+                parseExpected(29 /* GreaterThanToken */);
+            }
+            else {
+                parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
+                scanJsxText();
+            }
+            return finishNode(node);
+        }
+        function parseTypeAssertion() {
+            var node = createNode(184 /* TypeAssertionExpression */);
+            parseExpected(27 /* LessThanToken */);
+            node.type = parseType();
+            parseExpected(29 /* GreaterThanToken */);
+            node.expression = parseSimpleUnaryExpression();
+            return finishNode(node);
+        }
+        function parseMemberExpressionRest(expression) {
+            while (true) {
+                var dotToken = parseOptionalToken(23 /* DotToken */);
+                if (dotToken) {
+                    var propertyAccess = createNode(179 /* PropertyAccessExpression */, expression.pos);
+                    propertyAccess.expression = expression;
+                    propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+                    expression = finishNode(propertyAccess);
+                    continue;
+                }
+                if (token() === 51 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
+                    nextToken();
+                    var nonNullExpression = createNode(203 /* NonNullExpression */, expression.pos);
+                    nonNullExpression.expression = expression;
+                    expression = finishNode(nonNullExpression);
+                    continue;
+                }
+                // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
+                if (!inDecoratorContext() && parseOptional(21 /* OpenBracketToken */)) {
+                    var indexedAccess = createNode(180 /* ElementAccessExpression */, expression.pos);
+                    indexedAccess.expression = expression;
+                    // It's not uncommon for a user to write: "new Type[]".
+                    // Check for that common pattern and report a better error message.
+                    if (token() !== 22 /* CloseBracketToken */) {
+                        indexedAccess.argumentExpression = allowInAnd(parseExpression);
+                        if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
+                            var literal = indexedAccess.argumentExpression;
+                            literal.text = internIdentifier(literal.text);
+                        }
+                    }
+                    parseExpected(22 /* CloseBracketToken */);
+                    expression = finishNode(indexedAccess);
+                    continue;
+                }
+                if (token() === 13 /* NoSubstitutionTemplateLiteral */ || token() === 14 /* TemplateHead */) {
+                    var tagExpression = createNode(183 /* TaggedTemplateExpression */, expression.pos);
+                    tagExpression.tag = expression;
+                    tagExpression.template = token() === 13 /* NoSubstitutionTemplateLiteral */
+                        ? parseLiteralNode()
+                        : parseTemplateExpression();
+                    expression = finishNode(tagExpression);
+                    continue;
+                }
+                return expression;
+            }
+        }
+        function parseCallExpressionRest(expression) {
+            while (true) {
+                expression = parseMemberExpressionRest(expression);
+                if (token() === 27 /* LessThanToken */) {
+                    // See if this is the start of a generic invocation.  If so, consume it and
+                    // keep checking for postfix expressions.  Otherwise, it's just a '<' that's
+                    // part of an arithmetic expression.  Break out so we consume it higher in the
+                    // stack.
+                    var typeArguments = tryParse(parseTypeArgumentsInExpression);
+                    if (!typeArguments) {
+                        return expression;
+                    }
+                    var callExpr = createNode(181 /* CallExpression */, expression.pos);
+                    callExpr.expression = expression;
+                    callExpr.typeArguments = typeArguments;
+                    callExpr.arguments = parseArgumentList();
+                    expression = finishNode(callExpr);
+                    continue;
+                }
+                else if (token() === 19 /* OpenParenToken */) {
+                    var callExpr = createNode(181 /* CallExpression */, expression.pos);
+                    callExpr.expression = expression;
+                    callExpr.arguments = parseArgumentList();
+                    expression = finishNode(callExpr);
+                    continue;
+                }
+                return expression;
+            }
+        }
+        function parseArgumentList() {
+            parseExpected(19 /* OpenParenToken */);
+            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
+            parseExpected(20 /* CloseParenToken */);
+            return result;
+        }
+        function parseTypeArgumentsInExpression() {
+            if (!parseOptional(27 /* LessThanToken */)) {
+                return undefined;
+            }
+            var typeArguments = parseDelimitedList(19 /* TypeArguments */, parseType);
+            if (!parseExpected(29 /* GreaterThanToken */)) {
+                // If it doesn't have the closing >  then it's definitely not an type argument list.
+                return undefined;
+            }
+            // If we have a '<', then only parse this as a argument list if the type arguments
+            // are complete and we have an open paren.  if we don't, rewind and return nothing.
+            return typeArguments && canFollowTypeArgumentsInExpression()
+                ? typeArguments
+                : undefined;
+        }
+        function canFollowTypeArgumentsInExpression() {
+            switch (token()) {
+                case 19 /* OpenParenToken */: // foo<x>(
+                // this case are the only case where this token can legally follow a type argument
+                // list.  So we definitely want to treat this as a type arg list.
+                case 23 /* DotToken */: // foo<x>.
+                case 20 /* CloseParenToken */: // foo<x>)
+                case 22 /* CloseBracketToken */: // foo<x>]
+                case 56 /* ColonToken */: // foo<x>:
+                case 25 /* SemicolonToken */: // foo<x>;
+                case 55 /* QuestionToken */: // foo<x>?
+                case 32 /* EqualsEqualsToken */: // foo<x> ==
+                case 34 /* EqualsEqualsEqualsToken */: // foo<x> ===
+                case 33 /* ExclamationEqualsToken */: // foo<x> !=
+                case 35 /* ExclamationEqualsEqualsToken */: // foo<x> !==
+                case 53 /* AmpersandAmpersandToken */: // foo<x> &&
+                case 54 /* BarBarToken */: // foo<x> ||
+                case 50 /* CaretToken */: // foo<x> ^
+                case 48 /* AmpersandToken */: // foo<x> &
+                case 49 /* BarToken */: // foo<x> |
+                case 18 /* CloseBraceToken */: // foo<x> }
+                case 1 /* EndOfFileToken */:// foo<x>
+                    // these cases can't legally follow a type arg list.  However, they're not legal
+                    // expressions either.  The user is probably in the middle of a generic type. So
+                    // treat it as such.
+                    return true;
+                case 26 /* CommaToken */: // foo<x>,
+                case 17 /* OpenBraceToken */: // foo<x> {
+                // We don't want to treat these as type arguments.  Otherwise we'll parse this
+                // as an invocation expression.  Instead, we want to parse out the expression
+                // in isolation from the type arguments.
+                default:
+                    // Anything else treat as an expression.
+                    return false;
+            }
+        }
+        function parsePrimaryExpression() {
+            switch (token()) {
+                case 8 /* NumericLiteral */:
+                case 9 /* StringLiteral */:
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                    return parseLiteralNode();
+                case 99 /* ThisKeyword */:
+                case 97 /* SuperKeyword */:
+                case 95 /* NullKeyword */:
+                case 101 /* TrueKeyword */:
+                case 86 /* FalseKeyword */:
+                    return parseTokenNode();
+                case 19 /* OpenParenToken */:
+                    return parseParenthesizedExpression();
+                case 21 /* OpenBracketToken */:
+                    return parseArrayLiteralExpression();
+                case 17 /* OpenBraceToken */:
+                    return parseObjectLiteralExpression();
+                case 120 /* AsyncKeyword */:
+                    // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
+                    // If we encounter `async [no LineTerminator here] function` then this is an async
+                    // function; otherwise, its an identifier.
+                    if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
+                        break;
+                    }
+                    return parseFunctionExpression();
+                case 75 /* ClassKeyword */:
+                    return parseClassExpression();
+                case 89 /* FunctionKeyword */:
+                    return parseFunctionExpression();
+                case 94 /* NewKeyword */:
+                    return parseNewExpression();
+                case 41 /* SlashToken */:
+                case 63 /* SlashEqualsToken */:
+                    if (reScanSlashToken() === 12 /* RegularExpressionLiteral */) {
+                        return parseLiteralNode();
+                    }
+                    break;
+                case 14 /* TemplateHead */:
+                    return parseTemplateExpression();
+            }
+            return parseIdentifier(ts.Diagnostics.Expression_expected);
+        }
+        function parseParenthesizedExpression() {
+            var node = createNode(185 /* ParenthesizedExpression */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            return addJSDocComment(finishNode(node));
+        }
+        function parseSpreadElement() {
+            var node = createNode(198 /* SpreadElement */);
+            parseExpected(24 /* DotDotDotToken */);
+            node.expression = parseAssignmentExpressionOrHigher();
+            return finishNode(node);
+        }
+        function parseArgumentOrArrayLiteralElement() {
+            return token() === 24 /* DotDotDotToken */ ? parseSpreadElement() :
+                token() === 26 /* CommaToken */ ? createNode(200 /* OmittedExpression */) :
+                    parseAssignmentExpressionOrHigher();
+        }
+        function parseArgumentExpression() {
+            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+        }
+        function parseArrayLiteralExpression() {
+            var node = createNode(177 /* ArrayLiteralExpression */);
+            parseExpected(21 /* OpenBracketToken */);
+            if (scanner.hasPrecedingLineBreak()) {
+                node.multiLine = true;
+            }
+            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
+            parseExpected(22 /* CloseBracketToken */);
+            return finishNode(node);
+        }
+        function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
+            if (parseContextualModifier(125 /* GetKeyword */)) {
+                return parseAccessorDeclaration(153 /* GetAccessor */, fullStart, decorators, modifiers);
+            }
+            else if (parseContextualModifier(135 /* SetKeyword */)) {
+                return parseAccessorDeclaration(154 /* SetAccessor */, fullStart, decorators, modifiers);
+            }
+            return undefined;
+        }
+        function parseObjectLiteralElement() {
+            var fullStart = scanner.getStartPos();
+            var dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
+            if (dotDotDotToken) {
+                var spreadElement = createNode(263 /* SpreadAssignment */, fullStart);
+                spreadElement.expression = parseAssignmentExpressionOrHigher();
+                return addJSDocComment(finishNode(spreadElement));
+            }
+            var decorators = parseDecorators();
+            var modifiers = parseModifiers();
+            var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+            if (accessor) {
+                return accessor;
+            }
+            var asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
+            var tokenIsIdentifier = isIdentifier();
+            var propertyName = parsePropertyName();
+            // Disallowing of optional property assignments happens in the grammar checker.
+            var questionToken = parseOptionalToken(55 /* QuestionToken */);
+            if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
+                return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
+            }
+            // check if it is short-hand property assignment or normal property assignment
+            // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
+            // CoverInitializedName[Yield] :
+            //     IdentifierReference[?Yield] Initializer[In, ?Yield]
+            // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
+            var isShorthandPropertyAssignment = tokenIsIdentifier && (token() === 26 /* CommaToken */ || token() === 18 /* CloseBraceToken */ || token() === 58 /* EqualsToken */);
+            if (isShorthandPropertyAssignment) {
+                var shorthandDeclaration = createNode(262 /* ShorthandPropertyAssignment */, fullStart);
+                shorthandDeclaration.name = propertyName;
+                shorthandDeclaration.questionToken = questionToken;
+                var equalsToken = parseOptionalToken(58 /* EqualsToken */);
+                if (equalsToken) {
+                    shorthandDeclaration.equalsToken = equalsToken;
+                    shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
+                }
+                return addJSDocComment(finishNode(shorthandDeclaration));
+            }
+            else {
+                var propertyAssignment = createNode(261 /* PropertyAssignment */, fullStart);
+                propertyAssignment.modifiers = modifiers;
+                propertyAssignment.name = propertyName;
+                propertyAssignment.questionToken = questionToken;
+                parseExpected(56 /* ColonToken */);
+                propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
+                return addJSDocComment(finishNode(propertyAssignment));
+            }
+        }
+        function parseObjectLiteralExpression() {
+            var node = createNode(178 /* ObjectLiteralExpression */);
+            parseExpected(17 /* OpenBraceToken */);
+            if (scanner.hasPrecedingLineBreak()) {
+                node.multiLine = true;
+            }
+            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
+            parseExpected(18 /* CloseBraceToken */);
+            return finishNode(node);
+        }
+        function parseFunctionExpression() {
+            // GeneratorExpression:
+            //      function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
+            //
+            // FunctionExpression:
+            //      function BindingIdentifier[opt](FormalParameters){ FunctionBody }
+            var saveDecoratorContext = inDecoratorContext();
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ false);
+            }
+            var node = createNode(186 /* FunctionExpression */);
+            node.modifiers = parseModifiers();
+            parseExpected(89 /* FunctionKeyword */);
+            node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
+            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
+            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
+            node.name =
+                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
+                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
+                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
+                            parseOptionalIdentifier();
+            fillSignature(56 /* ColonToken */, isGenerator | isAsync, node);
+            node.body = parseFunctionBlock(isGenerator | isAsync);
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ true);
+            }
+            return addJSDocComment(finishNode(node));
+        }
+        function parseOptionalIdentifier() {
+            return isIdentifier() ? parseIdentifier() : undefined;
+        }
+        function parseNewExpression() {
+            var fullStart = scanner.getStartPos();
+            parseExpected(94 /* NewKeyword */);
+            if (parseOptional(23 /* DotToken */)) {
+                var node_1 = createNode(204 /* MetaProperty */, fullStart);
+                node_1.keywordToken = 94 /* NewKeyword */;
+                node_1.name = parseIdentifierName();
+                return finishNode(node_1);
+            }
+            var node = createNode(182 /* NewExpression */, fullStart);
+            node.expression = parseMemberExpressionOrHigher();
+            node.typeArguments = tryParse(parseTypeArgumentsInExpression);
+            if (node.typeArguments || token() === 19 /* OpenParenToken */) {
+                node.arguments = parseArgumentList();
+            }
+            return finishNode(node);
+        }
+        // STATEMENTS
+        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
+            var node = createNode(207 /* Block */);
+            if (parseExpected(17 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
+                if (scanner.hasPrecedingLineBreak()) {
+                    node.multiLine = true;
+                }
+                node.statements = parseList(1 /* BlockStatements */, parseStatement);
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                node.statements = createMissingList();
+            }
+            return finishNode(node);
+        }
+        function parseFunctionBlock(flags, diagnosticMessage) {
+            var savedYieldContext = inYieldContext();
+            setYieldContext(!!(flags & 1 /* Yield */));
+            var savedAwaitContext = inAwaitContext();
+            setAwaitContext(!!(flags & 2 /* Await */));
+            // We may be in a [Decorator] context when parsing a function expression or
+            // arrow function. The body of the function is not in [Decorator] context.
+            var saveDecoratorContext = inDecoratorContext();
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ false);
+            }
+            var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage);
+            if (saveDecoratorContext) {
+                setDecoratorContext(/*val*/ true);
+            }
+            setYieldContext(savedYieldContext);
+            setAwaitContext(savedAwaitContext);
+            return block;
+        }
+        function parseEmptyStatement() {
+            var node = createNode(209 /* EmptyStatement */);
+            parseExpected(25 /* SemicolonToken */);
+            return finishNode(node);
+        }
+        function parseIfStatement() {
+            var node = createNode(211 /* IfStatement */);
+            parseExpected(90 /* IfKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            node.thenStatement = parseStatement();
+            node.elseStatement = parseOptional(82 /* ElseKeyword */) ? parseStatement() : undefined;
+            return finishNode(node);
+        }
+        function parseDoStatement() {
+            var node = createNode(212 /* DoStatement */);
+            parseExpected(81 /* DoKeyword */);
+            node.statement = parseStatement();
+            parseExpected(106 /* WhileKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
+            // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
+            // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
+            //  do;while(0)x will have a semicolon inserted before x.
+            parseOptional(25 /* SemicolonToken */);
+            return finishNode(node);
+        }
+        function parseWhileStatement() {
+            var node = createNode(213 /* WhileStatement */);
+            parseExpected(106 /* WhileKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            node.statement = parseStatement();
+            return finishNode(node);
+        }
+        function parseForOrForInOrForOfStatement() {
+            var pos = getNodePos();
+            parseExpected(88 /* ForKeyword */);
+            var awaitToken = parseOptionalToken(121 /* AwaitKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            var initializer = undefined;
+            if (token() !== 25 /* SemicolonToken */) {
+                if (token() === 104 /* VarKeyword */ || token() === 110 /* LetKeyword */ || token() === 76 /* ConstKeyword */) {
+                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
+                }
+                else {
+                    initializer = disallowInAnd(parseExpression);
+                }
+            }
+            var forOrForInOrForOfStatement;
+            if (awaitToken ? parseExpected(142 /* OfKeyword */) : parseOptional(142 /* OfKeyword */)) {
+                var forOfStatement = createNode(216 /* ForOfStatement */, pos);
+                forOfStatement.awaitModifier = awaitToken;
+                forOfStatement.initializer = initializer;
+                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
+                parseExpected(20 /* CloseParenToken */);
+                forOrForInOrForOfStatement = forOfStatement;
+            }
+            else if (parseOptional(92 /* InKeyword */)) {
+                var forInStatement = createNode(215 /* ForInStatement */, pos);
+                forInStatement.initializer = initializer;
+                forInStatement.expression = allowInAnd(parseExpression);
+                parseExpected(20 /* CloseParenToken */);
+                forOrForInOrForOfStatement = forInStatement;
+            }
+            else {
+                var forStatement = createNode(214 /* ForStatement */, pos);
+                forStatement.initializer = initializer;
+                parseExpected(25 /* SemicolonToken */);
+                if (token() !== 25 /* SemicolonToken */ && token() !== 20 /* CloseParenToken */) {
+                    forStatement.condition = allowInAnd(parseExpression);
+                }
+                parseExpected(25 /* SemicolonToken */);
+                if (token() !== 20 /* CloseParenToken */) {
+                    forStatement.incrementor = allowInAnd(parseExpression);
+                }
+                parseExpected(20 /* CloseParenToken */);
+                forOrForInOrForOfStatement = forStatement;
+            }
+            forOrForInOrForOfStatement.statement = parseStatement();
+            return finishNode(forOrForInOrForOfStatement);
+        }
+        function parseBreakOrContinueStatement(kind) {
+            var node = createNode(kind);
+            parseExpected(kind === 218 /* BreakStatement */ ? 72 /* BreakKeyword */ : 77 /* ContinueKeyword */);
+            if (!canParseSemicolon()) {
+                node.label = parseIdentifier();
+            }
+            parseSemicolon();
+            return finishNode(node);
+        }
+        function parseReturnStatement() {
+            var node = createNode(219 /* ReturnStatement */);
+            parseExpected(96 /* ReturnKeyword */);
+            if (!canParseSemicolon()) {
+                node.expression = allowInAnd(parseExpression);
+            }
+            parseSemicolon();
+            return finishNode(node);
+        }
+        function parseWithStatement() {
+            var node = createNode(220 /* WithStatement */);
+            parseExpected(107 /* WithKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            node.statement = parseStatement();
+            return finishNode(node);
+        }
+        function parseCaseClause() {
+            var node = createNode(257 /* CaseClause */);
+            parseExpected(73 /* CaseKeyword */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(56 /* ColonToken */);
+            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+            return finishNode(node);
+        }
+        function parseDefaultClause() {
+            var node = createNode(258 /* DefaultClause */);
+            parseExpected(79 /* DefaultKeyword */);
+            parseExpected(56 /* ColonToken */);
+            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+            return finishNode(node);
+        }
+        function parseCaseOrDefaultClause() {
+            return token() === 73 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
+        }
+        function parseSwitchStatement() {
+            var node = createNode(221 /* SwitchStatement */);
+            parseExpected(98 /* SwitchKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = allowInAnd(parseExpression);
+            parseExpected(20 /* CloseParenToken */);
+            var caseBlock = createNode(235 /* CaseBlock */, scanner.getStartPos());
+            parseExpected(17 /* OpenBraceToken */);
+            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
+            parseExpected(18 /* CloseBraceToken */);
+            node.caseBlock = finishNode(caseBlock);
+            return finishNode(node);
+        }
+        function parseThrowStatement() {
+            // ThrowStatement[Yield] :
+            //      throw [no LineTerminator here]Expression[In, ?Yield];
+            // Because of automatic semicolon insertion, we need to report error if this
+            // throw could be terminated with a semicolon.  Note: we can't call 'parseExpression'
+            // directly as that might consume an expression on the following line.
+            // We just return 'undefined' in that case.  The actual error will be reported in the
+            // grammar walker.
+            var node = createNode(223 /* ThrowStatement */);
+            parseExpected(100 /* ThrowKeyword */);
+            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+            parseSemicolon();
+            return finishNode(node);
+        }
+        // TODO: Review for error recovery
+        function parseTryStatement() {
+            var node = createNode(224 /* TryStatement */);
+            parseExpected(102 /* TryKeyword */);
+            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
+            node.catchClause = token() === 74 /* CatchKeyword */ ? parseCatchClause() : undefined;
+            // If we don't have a catch clause, then we must have a finally clause.  Try to parse
+            // one out no matter what.
+            if (!node.catchClause || token() === 87 /* FinallyKeyword */) {
+                parseExpected(87 /* FinallyKeyword */);
+                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
+            }
+            return finishNode(node);
+        }
+        function parseCatchClause() {
+            var result = createNode(260 /* CatchClause */);
+            parseExpected(74 /* CatchKeyword */);
+            if (parseOptional(19 /* OpenParenToken */)) {
+                result.variableDeclaration = parseVariableDeclaration();
+                parseExpected(20 /* CloseParenToken */);
+            }
+            else {
+                // Keep shape of node to avoid degrading performance.
+                result.variableDeclaration = undefined;
+            }
+            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
+            return finishNode(result);
+        }
+        function parseDebuggerStatement() {
+            var node = createNode(225 /* DebuggerStatement */);
+            parseExpected(78 /* DebuggerKeyword */);
+            parseSemicolon();
+            return finishNode(node);
+        }
+        function parseExpressionOrLabeledStatement() {
+            // Avoiding having to do the lookahead for a labeled statement by just trying to parse
+            // out an expression, seeing if it is identifier and then seeing if it is followed by
+            // a colon.
+            var fullStart = scanner.getStartPos();
+            var expression = allowInAnd(parseExpression);
+            if (expression.kind === 71 /* Identifier */ && parseOptional(56 /* ColonToken */)) {
+                var labeledStatement = createNode(222 /* LabeledStatement */, fullStart);
+                labeledStatement.label = expression;
+                labeledStatement.statement = parseStatement();
+                return addJSDocComment(finishNode(labeledStatement));
+            }
+            else {
+                var expressionStatement = createNode(210 /* ExpressionStatement */, fullStart);
+                expressionStatement.expression = expression;
+                parseSemicolon();
+                return addJSDocComment(finishNode(expressionStatement));
+            }
+        }
+        function nextTokenIsIdentifierOrKeywordOnSameLine() {
+            nextToken();
+            return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
+        }
+        function nextTokenIsClassKeywordOnSameLine() {
+            nextToken();
+            return token() === 75 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak();
+        }
+        function nextTokenIsFunctionKeywordOnSameLine() {
+            nextToken();
+            return token() === 89 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
+        }
+        function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
+            nextToken();
+            return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* StringLiteral */) && !scanner.hasPrecedingLineBreak();
+        }
+        function isDeclaration() {
+            while (true) {
+                switch (token()) {
+                    case 104 /* VarKeyword */:
+                    case 110 /* LetKeyword */:
+                    case 76 /* ConstKeyword */:
+                    case 89 /* FunctionKeyword */:
+                    case 75 /* ClassKeyword */:
+                    case 83 /* EnumKeyword */:
+                        return true;
+                    // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
+                    // however, an identifier cannot be followed by another identifier on the same line. This is what we
+                    // count on to parse out the respective declarations. For instance, we exploit this to say that
+                    //
+                    //    namespace n
+                    //
+                    // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
+                    //
+                    //    namespace
+                    //    n
+                    //
+                    // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
+                    // We need to look one token ahead to see if it permissible to try parsing a declaration.
+                    //
+                    // *Note*: 'interface' is actually a strict mode reserved word. So while
+                    //
+                    //   "use strict"
+                    //   interface
+                    //   I {}
+                    //
+                    // could be legal, it would add complexity for very little gain.
+                    case 109 /* InterfaceKeyword */:
+                    case 138 /* TypeKeyword */:
+                        return nextTokenIsIdentifierOnSameLine();
+                    case 128 /* ModuleKeyword */:
+                    case 129 /* NamespaceKeyword */:
+                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
+                    case 117 /* AbstractKeyword */:
+                    case 120 /* AsyncKeyword */:
+                    case 124 /* DeclareKeyword */:
+                    case 112 /* PrivateKeyword */:
+                    case 113 /* ProtectedKeyword */:
+                    case 114 /* PublicKeyword */:
+                    case 131 /* ReadonlyKeyword */:
+                        nextToken();
+                        // ASI takes effect for this modifier.
+                        if (scanner.hasPrecedingLineBreak()) {
+                            return false;
+                        }
+                        continue;
+                    case 141 /* GlobalKeyword */:
+                        nextToken();
+                        return token() === 17 /* OpenBraceToken */ || token() === 71 /* Identifier */ || token() === 84 /* ExportKeyword */;
+                    case 91 /* ImportKeyword */:
+                        nextToken();
+                        return token() === 9 /* StringLiteral */ || token() === 39 /* AsteriskToken */ ||
+                            token() === 17 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token());
+                    case 84 /* ExportKeyword */:
+                        nextToken();
+                        if (token() === 58 /* EqualsToken */ || token() === 39 /* AsteriskToken */ ||
+                            token() === 17 /* OpenBraceToken */ || token() === 79 /* DefaultKeyword */ ||
+                            token() === 118 /* AsKeyword */) {
+                            return true;
+                        }
+                        continue;
+                    case 115 /* StaticKeyword */:
+                        nextToken();
+                        continue;
+                    default:
+                        return false;
+                }
+            }
+        }
+        function isStartOfDeclaration() {
+            return lookAhead(isDeclaration);
+        }
+        function isStartOfStatement() {
+            switch (token()) {
+                case 57 /* AtToken */:
+                case 25 /* SemicolonToken */:
+                case 17 /* OpenBraceToken */:
+                case 104 /* VarKeyword */:
+                case 110 /* LetKeyword */:
+                case 89 /* FunctionKeyword */:
+                case 75 /* ClassKeyword */:
+                case 83 /* EnumKeyword */:
+                case 90 /* IfKeyword */:
+                case 81 /* DoKeyword */:
+                case 106 /* WhileKeyword */:
+                case 88 /* ForKeyword */:
+                case 77 /* ContinueKeyword */:
+                case 72 /* BreakKeyword */:
+                case 96 /* ReturnKeyword */:
+                case 107 /* WithKeyword */:
+                case 98 /* SwitchKeyword */:
+                case 100 /* ThrowKeyword */:
+                case 102 /* TryKeyword */:
+                case 78 /* DebuggerKeyword */:
+                // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
+                // however, we say they are here so that we may gracefully parse them and error later.
+                case 74 /* CatchKeyword */:
+                case 87 /* FinallyKeyword */:
+                    return true;
+                case 91 /* ImportKeyword */:
+                    return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan);
+                case 76 /* ConstKeyword */:
+                case 84 /* ExportKeyword */:
+                    return isStartOfDeclaration();
+                case 120 /* AsyncKeyword */:
+                case 124 /* DeclareKeyword */:
+                case 109 /* InterfaceKeyword */:
+                case 128 /* ModuleKeyword */:
+                case 129 /* NamespaceKeyword */:
+                case 138 /* TypeKeyword */:
+                case 141 /* GlobalKeyword */:
+                    // When these don't start a declaration, they're an identifier in an expression statement
+                    return true;
+                case 114 /* PublicKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 115 /* StaticKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                    // When these don't start a declaration, they may be the start of a class member if an identifier
+                    // immediately follows. Otherwise they're an identifier in an expression statement.
+                    return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
+                default:
+                    return isStartOfExpression();
+            }
+        }
+        function nextTokenIsIdentifierOrStartOfDestructuring() {
+            nextToken();
+            return isIdentifier() || token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */;
+        }
+        function isLetDeclaration() {
+            // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
+            // or [.
+            return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+        }
+        function parseStatement() {
+            switch (token()) {
+                case 25 /* SemicolonToken */:
+                    return parseEmptyStatement();
+                case 17 /* OpenBraceToken */:
+                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
+                case 104 /* VarKeyword */:
+                    return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+                case 110 /* LetKeyword */:
+                    if (isLetDeclaration()) {
+                        return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+                    }
+                    break;
+                case 89 /* FunctionKeyword */:
+                    return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+                case 75 /* ClassKeyword */:
+                    return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+                case 90 /* IfKeyword */:
+                    return parseIfStatement();
+                case 81 /* DoKeyword */:
+                    return parseDoStatement();
+                case 106 /* WhileKeyword */:
+                    return parseWhileStatement();
+                case 88 /* ForKeyword */:
+                    return parseForOrForInOrForOfStatement();
+                case 77 /* ContinueKeyword */:
+                    return parseBreakOrContinueStatement(217 /* ContinueStatement */);
+                case 72 /* BreakKeyword */:
+                    return parseBreakOrContinueStatement(218 /* BreakStatement */);
+                case 96 /* ReturnKeyword */:
+                    return parseReturnStatement();
+                case 107 /* WithKeyword */:
+                    return parseWithStatement();
+                case 98 /* SwitchKeyword */:
+                    return parseSwitchStatement();
+                case 100 /* ThrowKeyword */:
+                    return parseThrowStatement();
+                case 102 /* TryKeyword */:
+                // Include 'catch' and 'finally' for error recovery.
+                case 74 /* CatchKeyword */:
+                case 87 /* FinallyKeyword */:
+                    return parseTryStatement();
+                case 78 /* DebuggerKeyword */:
+                    return parseDebuggerStatement();
+                case 57 /* AtToken */:
+                    return parseDeclaration();
+                case 120 /* AsyncKeyword */:
+                case 109 /* InterfaceKeyword */:
+                case 138 /* TypeKeyword */:
+                case 128 /* ModuleKeyword */:
+                case 129 /* NamespaceKeyword */:
+                case 124 /* DeclareKeyword */:
+                case 76 /* ConstKeyword */:
+                case 83 /* EnumKeyword */:
+                case 84 /* ExportKeyword */:
+                case 91 /* ImportKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 114 /* PublicKeyword */:
+                case 117 /* AbstractKeyword */:
+                case 115 /* StaticKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                case 141 /* GlobalKeyword */:
+                    if (isStartOfDeclaration()) {
+                        return parseDeclaration();
+                    }
+                    break;
+            }
+            return parseExpressionOrLabeledStatement();
+        }
+        function parseDeclaration() {
+            var fullStart = getNodePos();
+            var decorators = parseDecorators();
+            var modifiers = parseModifiers();
+            switch (token()) {
+                case 104 /* VarKeyword */:
+                case 110 /* LetKeyword */:
+                case 76 /* ConstKeyword */:
+                    return parseVariableStatement(fullStart, decorators, modifiers);
+                case 89 /* FunctionKeyword */:
+                    return parseFunctionDeclaration(fullStart, decorators, modifiers);
+                case 75 /* ClassKeyword */:
+                    return parseClassDeclaration(fullStart, decorators, modifiers);
+                case 109 /* InterfaceKeyword */:
+                    return parseInterfaceDeclaration(fullStart, decorators, modifiers);
+                case 138 /* TypeKeyword */:
+                    return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
+                case 83 /* EnumKeyword */:
+                    return parseEnumDeclaration(fullStart, decorators, modifiers);
+                case 141 /* GlobalKeyword */:
+                case 128 /* ModuleKeyword */:
+                case 129 /* NamespaceKeyword */:
+                    return parseModuleDeclaration(fullStart, decorators, modifiers);
+                case 91 /* ImportKeyword */:
+                    return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
+                case 84 /* ExportKeyword */:
+                    nextToken();
+                    switch (token()) {
+                        case 79 /* DefaultKeyword */:
+                        case 58 /* EqualsToken */:
+                            return parseExportAssignment(fullStart, decorators, modifiers);
+                        case 118 /* AsKeyword */:
+                            return parseNamespaceExportDeclaration(fullStart, decorators, modifiers);
+                        default:
+                            return parseExportDeclaration(fullStart, decorators, modifiers);
+                    }
+                default:
+                    if (decorators || modifiers) {
+                        // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
+                        // would follow. For recovery and error reporting purposes, return an incomplete declaration.
+                        var node = createMissingNode(247 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+                        node.pos = fullStart;
+                        node.decorators = decorators;
+                        node.modifiers = modifiers;
+                        return finishNode(node);
+                    }
+            }
+        }
+        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+            nextToken();
+            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 9 /* StringLiteral */);
+        }
+        function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) {
+            if (token() !== 17 /* OpenBraceToken */ && canParseSemicolon()) {
+                parseSemicolon();
+                return;
+            }
+            return parseFunctionBlock(flags, diagnosticMessage);
+        }
+        // DECLARATIONS
+        function parseArrayBindingElement() {
+            if (token() === 26 /* CommaToken */) {
+                return createNode(200 /* OmittedExpression */);
+            }
+            var node = createNode(176 /* BindingElement */);
+            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
+            node.name = parseIdentifierOrPattern();
+            node.initializer = parseInitializer(/*inParameter*/ false);
+            return finishNode(node);
+        }
+        function parseObjectBindingElement() {
+            var node = createNode(176 /* BindingElement */);
+            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
+            var tokenIsIdentifier = isIdentifier();
+            var propertyName = parsePropertyName();
+            if (tokenIsIdentifier && token() !== 56 /* ColonToken */) {
+                node.name = propertyName;
+            }
+            else {
+                parseExpected(56 /* ColonToken */);
+                node.propertyName = propertyName;
+                node.name = parseIdentifierOrPattern();
+            }
+            node.initializer = parseInitializer(/*inParameter*/ false);
+            return finishNode(node);
+        }
+        function parseObjectBindingPattern() {
+            var node = createNode(174 /* ObjectBindingPattern */);
+            parseExpected(17 /* OpenBraceToken */);
+            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
+            parseExpected(18 /* CloseBraceToken */);
+            return finishNode(node);
+        }
+        function parseArrayBindingPattern() {
+            var node = createNode(175 /* ArrayBindingPattern */);
+            parseExpected(21 /* OpenBracketToken */);
+            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
+            parseExpected(22 /* CloseBracketToken */);
+            return finishNode(node);
+        }
+        function isIdentifierOrPattern() {
+            return token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */ || isIdentifier();
+        }
+        function parseIdentifierOrPattern() {
+            if (token() === 21 /* OpenBracketToken */) {
+                return parseArrayBindingPattern();
+            }
+            if (token() === 17 /* OpenBraceToken */) {
+                return parseObjectBindingPattern();
+            }
+            return parseIdentifier();
+        }
+        function parseVariableDeclaration() {
+            var node = createNode(226 /* VariableDeclaration */);
+            node.name = parseIdentifierOrPattern();
+            node.type = parseTypeAnnotation();
+            if (!isInOrOfKeyword(token())) {
+                node.initializer = parseNonParameterInitializer();
+            }
+            return finishNode(node);
+        }
+        function parseVariableDeclarationList(inForStatementInitializer) {
+            var node = createNode(227 /* VariableDeclarationList */);
+            switch (token()) {
+                case 104 /* VarKeyword */:
+                    break;
+                case 110 /* LetKeyword */:
+                    node.flags |= 1 /* Let */;
+                    break;
+                case 76 /* ConstKeyword */:
+                    node.flags |= 2 /* Const */;
+                    break;
+                default:
+                    ts.Debug.fail();
+            }
+            nextToken();
+            // The user may have written the following:
+            //
+            //    for (let of X) { }
+            //
+            // In this case, we want to parse an empty declaration list, and then parse 'of'
+            // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
+            // So we need to look ahead to determine if 'of' should be treated as a keyword in
+            // this context.
+            // The checker will then give an error that there is an empty declaration list.
+            if (token() === 142 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
+                node.declarations = createMissingList();
+            }
+            else {
+                var savedDisallowIn = inDisallowInContext();
+                setDisallowInContext(inForStatementInitializer);
+                node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
+                setDisallowInContext(savedDisallowIn);
+            }
+            return finishNode(node);
+        }
+        function canFollowContextualOfKeyword() {
+            return nextTokenIsIdentifier() && nextToken() === 20 /* CloseParenToken */;
+        }
+        function parseVariableStatement(fullStart, decorators, modifiers) {
+            var node = createNode(208 /* VariableStatement */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
+            parseSemicolon();
+            return addJSDocComment(finishNode(node));
+        }
+        function parseFunctionDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(228 /* FunctionDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(89 /* FunctionKeyword */);
+            node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
+            node.name = ts.hasModifier(node, 512 /* Default */) ? parseOptionalIdentifier() : parseIdentifier();
+            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
+            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
+            fillSignature(56 /* ColonToken */, isGenerator | isAsync, node);
+            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected);
+            return addJSDocComment(finishNode(node));
+        }
+        function parseConstructorDeclaration(pos, decorators, modifiers) {
+            var node = createNode(152 /* Constructor */, pos);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(123 /* ConstructorKeyword */);
+            fillSignature(56 /* ColonToken */, 0 /* None */, node);
+            node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected);
+            return addJSDocComment(finishNode(node));
+        }
+        function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
+            var method = createNode(151 /* MethodDeclaration */, fullStart);
+            method.decorators = decorators;
+            method.modifiers = modifiers;
+            method.asteriskToken = asteriskToken;
+            method.name = name;
+            method.questionToken = questionToken;
+            var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */;
+            var isAsync = ts.hasModifier(method, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
+            fillSignature(56 /* ColonToken */, isGenerator | isAsync, method);
+            method.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
+            return addJSDocComment(finishNode(method));
+        }
+        function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
+            var property = createNode(149 /* PropertyDeclaration */, fullStart);
+            property.decorators = decorators;
+            property.modifiers = modifiers;
+            property.name = name;
+            property.questionToken = questionToken;
+            property.type = parseTypeAnnotation();
+            // For instance properties specifically, since they are evaluated inside the constructor,
+            // we do *not * want to parse yield expressions, so we specifically turn the yield context
+            // off. The grammar would look something like this:
+            //
+            //    MemberVariableDeclaration[Yield]:
+            //        AccessibilityModifier_opt   PropertyName   TypeAnnotation_opt   Initializer_opt[In];
+            //        AccessibilityModifier_opt  static_opt  PropertyName   TypeAnnotation_opt   Initializer_opt[In, ?Yield];
+            //
+            // The checker may still error in the static case to explicitly disallow the yield expression.
+            property.initializer = ts.hasModifier(property, 32 /* Static */)
+                ? allowInAnd(parseNonParameterInitializer)
+                : doOutsideOfContext(4096 /* YieldContext */ | 2048 /* DisallowInContext */, parseNonParameterInitializer);
+            parseSemicolon();
+            return addJSDocComment(finishNode(property));
+        }
+        function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
+            var asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
+            var name = parsePropertyName();
+            // Note: this is not legal as per the grammar.  But we allow it in the parser and
+            // report an error in the grammar checker.
+            var questionToken = parseOptionalToken(55 /* QuestionToken */);
+            if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
+                return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
+            }
+            else {
+                return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
+            }
+        }
+        function parseNonParameterInitializer() {
+            return parseInitializer(/*inParameter*/ false);
+        }
+        function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
+            var node = createNode(kind, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            node.name = parsePropertyName();
+            fillSignature(56 /* ColonToken */, 0 /* None */, node);
+            node.body = parseFunctionBlockOrSemicolon(0 /* None */);
+            return addJSDocComment(finishNode(node));
+        }
+        function isClassMemberModifier(idToken) {
+            switch (idToken) {
+                case 114 /* PublicKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 115 /* StaticKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+        function isClassMemberStart() {
+            var idToken;
+            if (token() === 57 /* AtToken */) {
+                return true;
+            }
+            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
+            while (ts.isModifierKind(token())) {
+                idToken = token();
+                // If the idToken is a class modifier (protected, private, public, and static), it is
+                // certain that we are starting to parse class member. This allows better error recovery
+                // Example:
+                //      public foo() ...     // true
+                //      public @dec blah ... // true; we will then report an error later
+                //      export public ...    // true; we will then report an error later
+                if (isClassMemberModifier(idToken)) {
+                    return true;
+                }
+                nextToken();
+            }
+            if (token() === 39 /* AsteriskToken */) {
+                return true;
+            }
+            // Try to get the first property-like token following all modifiers.
+            // This can either be an identifier or the 'get' or 'set' keywords.
+            if (isLiteralPropertyName()) {
+                idToken = token();
+                nextToken();
+            }
+            // Index signatures and computed properties are class members; we can parse.
+            if (token() === 21 /* OpenBracketToken */) {
+                return true;
+            }
+            // If we were able to get any potential identifier...
+            if (idToken !== undefined) {
+                // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
+                if (!ts.isKeyword(idToken) || idToken === 135 /* SetKeyword */ || idToken === 125 /* GetKeyword */) {
+                    return true;
+                }
+                // If it *is* a keyword, but not an accessor, check a little farther along
+                // to see if it should actually be parsed as a class member.
+                switch (token()) {
+                    case 19 /* OpenParenToken */: // Method declaration
+                    case 27 /* LessThanToken */: // Generic Method declaration
+                    case 56 /* ColonToken */: // Type Annotation for declaration
+                    case 58 /* EqualsToken */: // Initializer for declaration
+                    case 55 /* QuestionToken */:// Not valid, but permitted so that it gets caught later on.
+                        return true;
+                    default:
+                        // Covers
+                        //  - Semicolons     (declaration termination)
+                        //  - Closing braces (end-of-class, must be declaration)
+                        //  - End-of-files   (not valid, but permitted so that it gets caught later on)
+                        //  - Line-breaks    (enabling *automatic semicolon insertion*)
+                        return canParseSemicolon();
+                }
+            }
+            return false;
+        }
+        function parseDecorators() {
+            var list;
+            var listPos = getNodePos();
+            while (true) {
+                var decoratorStart = getNodePos();
+                if (!parseOptional(57 /* AtToken */)) {
+                    break;
+                }
+                var decorator = createNode(147 /* Decorator */, decoratorStart);
+                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
+                finishNode(decorator);
+                (list || (list = [])).push(decorator);
+            }
+            return list && createNodeArray(list, listPos);
+        }
+        /*
+         * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
+         * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
+         * and turns it into a standalone declaration), then it is better to parse it and report an error later.
+         *
+         * In such situations, 'permitInvalidConstAsModifier' should be set to true.
+         */
+        function parseModifiers(permitInvalidConstAsModifier) {
+            var list;
+            var listPos = getNodePos();
+            while (true) {
+                var modifierStart = scanner.getStartPos();
+                var modifierKind = token();
+                if (token() === 76 /* ConstKeyword */ && permitInvalidConstAsModifier) {
+                    // We need to ensure that any subsequent modifiers appear on the same line
+                    // so that when 'const' is a standalone declaration, we don't issue an error.
+                    if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
+                        break;
+                    }
+                }
+                else {
+                    if (!parseAnyContextualModifier()) {
+                        break;
+                    }
+                }
+                var modifier = finishNode(createNode(modifierKind, modifierStart));
+                (list || (list = [])).push(modifier);
+            }
+            return list && createNodeArray(list, listPos);
+        }
+        function parseModifiersForArrowFunction() {
+            var modifiers;
+            if (token() === 120 /* AsyncKeyword */) {
+                var modifierStart = scanner.getStartPos();
+                var modifierKind = token();
+                nextToken();
+                var modifier = finishNode(createNode(modifierKind, modifierStart));
+                modifiers = createNodeArray([modifier], modifierStart);
+            }
+            return modifiers;
+        }
+        function parseClassElement() {
+            if (token() === 25 /* SemicolonToken */) {
+                var result = createNode(206 /* SemicolonClassElement */);
+                nextToken();
+                return finishNode(result);
+            }
+            var fullStart = getNodePos();
+            var decorators = parseDecorators();
+            var modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true);
+            var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+            if (accessor) {
+                return accessor;
+            }
+            if (token() === 123 /* ConstructorKeyword */) {
+                return parseConstructorDeclaration(fullStart, decorators, modifiers);
+            }
+            if (isIndexSignature()) {
+                return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
+            }
+            // It is very important that we check this *after* checking indexers because
+            // the [ token can start an index signature or a computed property name
+            if (ts.tokenIsIdentifierOrKeyword(token()) ||
+                token() === 9 /* StringLiteral */ ||
+                token() === 8 /* NumericLiteral */ ||
+                token() === 39 /* AsteriskToken */ ||
+                token() === 21 /* OpenBracketToken */) {
+                return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+            }
+            if (decorators || modifiers) {
+                // treat this as a property declaration with a missing name.
+                var name = createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+                return parsePropertyDeclaration(fullStart, decorators, modifiers, name, /*questionToken*/ undefined);
+            }
+            // 'isClassMemberStart' should have hinted not to attempt parsing.
+            ts.Debug.fail("Should not have attempted to parse class member declaration.");
+        }
+        function parseClassExpression() {
+            return parseClassDeclarationOrExpression(
+            /*fullStart*/ scanner.getStartPos(), 
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, 199 /* ClassExpression */);
+        }
+        function parseClassDeclaration(fullStart, decorators, modifiers) {
+            return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 229 /* ClassDeclaration */);
+        }
+        function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
+            var node = createNode(kind, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(75 /* ClassKeyword */);
+            node.name = parseNameOfClassDeclarationOrExpression();
+            node.typeParameters = parseTypeParameters();
+            node.heritageClauses = parseHeritageClauses();
+            if (parseExpected(17 /* OpenBraceToken */)) {
+                // ClassTail[Yield,Await] : (Modified) See 14.5
+                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+                node.members = parseClassMembers();
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                node.members = createMissingList();
+            }
+            return addJSDocComment(finishNode(node));
+        }
+        function parseNameOfClassDeclarationOrExpression() {
+            // implements is a future reserved word so
+            // 'class implements' might mean either
+            // - class expression with omitted name, 'implements' starts heritage clause
+            // - class with name 'implements'
+            // 'isImplementsClause' helps to disambiguate between these two cases
+            return isIdentifier() && !isImplementsClause()
+                ? parseIdentifier()
+                : undefined;
+        }
+        function isImplementsClause() {
+            return token() === 108 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
+        }
+        function parseHeritageClauses() {
+            // ClassTail[Yield,Await] : (Modified) See 14.5
+            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+            if (isHeritageClause()) {
+                return parseList(21 /* HeritageClauses */, parseHeritageClause);
+            }
+            return undefined;
+        }
+        function parseHeritageClause() {
+            var tok = token();
+            if (tok === 85 /* ExtendsKeyword */ || tok === 108 /* ImplementsKeyword */) {
+                var node = createNode(259 /* HeritageClause */);
+                node.token = tok;
+                nextToken();
+                node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
+                return finishNode(node);
+            }
+            return undefined;
+        }
+        function parseExpressionWithTypeArguments() {
+            var node = createNode(201 /* ExpressionWithTypeArguments */);
+            node.expression = parseLeftHandSideExpressionOrHigher();
+            node.typeArguments = tryParseTypeArguments();
+            return finishNode(node);
+        }
+        function tryParseTypeArguments() {
+            return token() === 27 /* LessThanToken */
+                ? parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */)
+                : undefined;
+        }
+        function isHeritageClause() {
+            return token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
+        }
+        function parseClassMembers() {
+            return parseList(5 /* ClassMembers */, parseClassElement);
+        }
+        function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(230 /* InterfaceDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(109 /* InterfaceKeyword */);
+            node.name = parseIdentifier();
+            node.typeParameters = parseTypeParameters();
+            node.heritageClauses = parseHeritageClauses();
+            node.members = parseObjectTypeMembers();
+            return addJSDocComment(finishNode(node));
+        }
+        function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(231 /* TypeAliasDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(138 /* TypeKeyword */);
+            node.name = parseIdentifier();
+            node.typeParameters = parseTypeParameters();
+            parseExpected(58 /* EqualsToken */);
+            node.type = parseType();
+            parseSemicolon();
+            return addJSDocComment(finishNode(node));
+        }
+        // In an ambient declaration, the grammar only allows integer literals as initializers.
+        // In a non-ambient declaration, the grammar allows uninitialized members only in a
+        // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
+        // or any time an integer literal initializer is encountered.
+        function parseEnumMember() {
+            var node = createNode(264 /* EnumMember */, scanner.getStartPos());
+            node.name = parsePropertyName();
+            node.initializer = allowInAnd(parseNonParameterInitializer);
+            return addJSDocComment(finishNode(node));
+        }
+        function parseEnumDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(232 /* EnumDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            parseExpected(83 /* EnumKeyword */);
+            node.name = parseIdentifier();
+            if (parseExpected(17 /* OpenBraceToken */)) {
+                node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                node.members = createMissingList();
+            }
+            return addJSDocComment(finishNode(node));
+        }
+        function parseModuleBlock() {
+            var node = createNode(234 /* ModuleBlock */, scanner.getStartPos());
+            if (parseExpected(17 /* OpenBraceToken */)) {
+                node.statements = parseList(1 /* BlockStatements */, parseStatement);
+                parseExpected(18 /* CloseBraceToken */);
+            }
+            else {
+                node.statements = createMissingList();
+            }
+            return finishNode(node);
+        }
+        function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
+            var node = createNode(233 /* ModuleDeclaration */, fullStart);
+            // If we are parsing a dotted namespace name, we want to
+            // propagate the 'Namespace' flag across the names if set.
+            var namespaceFlag = flags & 16 /* Namespace */;
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            node.flags |= flags;
+            node.name = parseIdentifier();
+            node.body = parseOptional(23 /* DotToken */)
+                ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 4 /* NestedNamespace */ | namespaceFlag)
+                : parseModuleBlock();
+            return addJSDocComment(finishNode(node));
+        }
+        function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(233 /* ModuleDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            if (token() === 141 /* GlobalKeyword */) {
+                // parse 'global' as name of global scope augmentation
+                node.name = parseIdentifier();
+                node.flags |= 512 /* GlobalAugmentation */;
+            }
+            else {
+                node.name = parseLiteralNode();
+                node.name.text = internIdentifier(node.name.text);
+            }
+            if (token() === 17 /* OpenBraceToken */) {
+                node.body = parseModuleBlock();
+            }
+            else {
+                parseSemicolon();
+            }
+            return finishNode(node);
+        }
+        function parseModuleDeclaration(fullStart, decorators, modifiers) {
+            var flags = 0;
+            if (token() === 141 /* GlobalKeyword */) {
+                // global augmentation
+                return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+            }
+            else if (parseOptional(129 /* NamespaceKeyword */)) {
+                flags |= 16 /* Namespace */;
+            }
+            else {
+                parseExpected(128 /* ModuleKeyword */);
+                if (token() === 9 /* StringLiteral */) {
+                    return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+                }
+            }
+            return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
+        }
+        function isExternalModuleReference() {
+            return token() === 132 /* RequireKeyword */ &&
+                lookAhead(nextTokenIsOpenParen);
+        }
+        function nextTokenIsOpenParen() {
+            return nextToken() === 19 /* OpenParenToken */;
+        }
+        function nextTokenIsSlash() {
+            return nextToken() === 41 /* SlashToken */;
+        }
+        function parseNamespaceExportDeclaration(fullStart, decorators, modifiers) {
+            var exportDeclaration = createNode(236 /* NamespaceExportDeclaration */, fullStart);
+            exportDeclaration.decorators = decorators;
+            exportDeclaration.modifiers = modifiers;
+            parseExpected(118 /* AsKeyword */);
+            parseExpected(129 /* NamespaceKeyword */);
+            exportDeclaration.name = parseIdentifier();
+            parseSemicolon();
+            return finishNode(exportDeclaration);
+        }
+        function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
+            parseExpected(91 /* ImportKeyword */);
+            var afterImportPos = scanner.getStartPos();
+            var identifier;
+            if (isIdentifier()) {
+                identifier = parseIdentifier();
+                if (token() !== 26 /* CommaToken */ && token() !== 140 /* FromKeyword */) {
+                    return parseImportEqualsDeclaration(fullStart, decorators, modifiers, identifier);
+                }
+            }
+            // Import statement
+            var importDeclaration = createNode(238 /* ImportDeclaration */, fullStart);
+            importDeclaration.decorators = decorators;
+            importDeclaration.modifiers = modifiers;
+            // ImportDeclaration:
+            //  import ImportClause from ModuleSpecifier ;
+            //  import ModuleSpecifier;
+            if (identifier || // import id
+                token() === 39 /* AsteriskToken */ || // import *
+                token() === 17 /* OpenBraceToken */) {
+                importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
+                parseExpected(140 /* FromKeyword */);
+            }
+            importDeclaration.moduleSpecifier = parseModuleSpecifier();
+            parseSemicolon();
+            return finishNode(importDeclaration);
+        }
+        function parseImportEqualsDeclaration(fullStart, decorators, modifiers, identifier) {
+            var importEqualsDeclaration = createNode(237 /* ImportEqualsDeclaration */, fullStart);
+            importEqualsDeclaration.decorators = decorators;
+            importEqualsDeclaration.modifiers = modifiers;
+            importEqualsDeclaration.name = identifier;
+            parseExpected(58 /* EqualsToken */);
+            importEqualsDeclaration.moduleReference = parseModuleReference();
+            parseSemicolon();
+            return addJSDocComment(finishNode(importEqualsDeclaration));
+        }
+        function parseImportClause(identifier, fullStart) {
+            // ImportClause:
+            //  ImportedDefaultBinding
+            //  NameSpaceImport
+            //  NamedImports
+            //  ImportedDefaultBinding, NameSpaceImport
+            //  ImportedDefaultBinding, NamedImports
+            var importClause = createNode(239 /* ImportClause */, fullStart);
+            if (identifier) {
+                // ImportedDefaultBinding:
+                //  ImportedBinding
+                importClause.name = identifier;
+            }
+            // If there was no default import or if there is comma token after default import
+            // parse namespace or named imports
+            if (!importClause.name ||
+                parseOptional(26 /* CommaToken */)) {
+                importClause.namedBindings = token() === 39 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(241 /* NamedImports */);
+            }
+            return finishNode(importClause);
+        }
+        function parseModuleReference() {
+            return isExternalModuleReference()
+                ? parseExternalModuleReference()
+                : parseEntityName(/*allowReservedWords*/ false);
+        }
+        function parseExternalModuleReference() {
+            var node = createNode(248 /* ExternalModuleReference */);
+            parseExpected(132 /* RequireKeyword */);
+            parseExpected(19 /* OpenParenToken */);
+            node.expression = parseModuleSpecifier();
+            parseExpected(20 /* CloseParenToken */);
+            return finishNode(node);
+        }
+        function parseModuleSpecifier() {
+            if (token() === 9 /* StringLiteral */) {
+                var result = parseLiteralNode();
+                result.text = internIdentifier(result.text);
+                return result;
+            }
+            else {
+                // We allow arbitrary expressions here, even though the grammar only allows string
+                // literals.  We check to ensure that it is only a string literal later in the grammar
+                // check pass.
+                return parseExpression();
+            }
+        }
+        function parseNamespaceImport() {
+            // NameSpaceImport:
+            //  * as ImportedBinding
+            var namespaceImport = createNode(240 /* NamespaceImport */);
+            parseExpected(39 /* AsteriskToken */);
+            parseExpected(118 /* AsKeyword */);
+            namespaceImport.name = parseIdentifier();
+            return finishNode(namespaceImport);
+        }
+        function parseNamedImportsOrExports(kind) {
+            var node = createNode(kind);
+            // NamedImports:
+            //  { }
+            //  { ImportsList }
+            //  { ImportsList, }
+            // ImportsList:
+            //  ImportSpecifier
+            //  ImportsList, ImportSpecifier
+            node.elements = parseBracketedList(22 /* ImportOrExportSpecifiers */, kind === 241 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 17 /* OpenBraceToken */, 18 /* CloseBraceToken */);
+            return finishNode(node);
+        }
+        function parseExportSpecifier() {
+            return parseImportOrExportSpecifier(246 /* ExportSpecifier */);
+        }
+        function parseImportSpecifier() {
+            return parseImportOrExportSpecifier(242 /* ImportSpecifier */);
+        }
+        function parseImportOrExportSpecifier(kind) {
+            var node = createNode(kind);
+            // ImportSpecifier:
+            //   BindingIdentifier
+            //   IdentifierName as BindingIdentifier
+            // ExportSpecifier:
+            //   IdentifierName
+            //   IdentifierName as IdentifierName
+            var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
+            var checkIdentifierStart = scanner.getTokenPos();
+            var checkIdentifierEnd = scanner.getTextPos();
+            var identifierName = parseIdentifierName();
+            if (token() === 118 /* AsKeyword */) {
+                node.propertyName = identifierName;
+                parseExpected(118 /* AsKeyword */);
+                checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
+                checkIdentifierStart = scanner.getTokenPos();
+                checkIdentifierEnd = scanner.getTextPos();
+                node.name = parseIdentifierName();
+            }
+            else {
+                node.name = identifierName;
+            }
+            if (kind === 242 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
+                // Report error identifier expected
+                parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
+            }
+            return finishNode(node);
+        }
+        function parseExportDeclaration(fullStart, decorators, modifiers) {
+            var node = createNode(244 /* ExportDeclaration */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            if (parseOptional(39 /* AsteriskToken */)) {
+                parseExpected(140 /* FromKeyword */);
+                node.moduleSpecifier = parseModuleSpecifier();
+            }
+            else {
+                node.exportClause = parseNamedImportsOrExports(245 /* NamedExports */);
+                // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
+                // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
+                // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
+                if (token() === 140 /* FromKeyword */ || (token() === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
+                    parseExpected(140 /* FromKeyword */);
+                    node.moduleSpecifier = parseModuleSpecifier();
+                }
+            }
+            parseSemicolon();
+            return finishNode(node);
+        }
+        function parseExportAssignment(fullStart, decorators, modifiers) {
+            var node = createNode(243 /* ExportAssignment */, fullStart);
+            node.decorators = decorators;
+            node.modifiers = modifiers;
+            if (parseOptional(58 /* EqualsToken */)) {
+                node.isExportEquals = true;
+            }
+            else {
+                parseExpected(79 /* DefaultKeyword */);
+            }
+            node.expression = parseAssignmentExpressionOrHigher();
+            parseSemicolon();
+            return finishNode(node);
+        }
+        function processReferenceComments(sourceFile) {
+            var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
+            var referencedFiles = [];
+            var typeReferenceDirectives = [];
+            var amdDependencies = [];
+            var amdModuleName;
+            var checkJsDirective = undefined;
+            // Keep scanning all the leading trivia in the file until we get to something that
+            // isn't trivia.  Any single line comment will be analyzed to see if it is a
+            // reference comment.
+            while (true) {
+                var kind = triviaScanner.scan();
+                if (kind !== 2 /* SingleLineCommentTrivia */) {
+                    if (ts.isTrivia(kind)) {
+                        continue;
+                    }
+                    else {
+                        break;
+                    }
+                }
+                var range = {
+                    kind: triviaScanner.getToken(),
+                    pos: triviaScanner.getTokenPos(),
+                    end: triviaScanner.getTextPos(),
+                };
+                var comment = sourceText.substring(range.pos, range.end);
+                var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
+                if (referencePathMatchResult) {
+                    var fileReference = referencePathMatchResult.fileReference;
+                    sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
+                    var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
+                    if (fileReference) {
+                        if (referencePathMatchResult.isTypeReferenceDirective) {
+                            typeReferenceDirectives.push(fileReference);
+                        }
+                        else {
+                            referencedFiles.push(fileReference);
+                        }
+                    }
+                    if (diagnosticMessage) {
+                        parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
+                    }
+                }
+                else {
+                    var amdModuleNameRegEx = /^\/\/\/\s*<amd-module\s+name\s*=\s*('|")(.+?)\1/gim;
+                    var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment);
+                    if (amdModuleNameMatchResult) {
+                        if (amdModuleName) {
+                            parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments));
+                        }
+                        amdModuleName = amdModuleNameMatchResult[2];
+                    }
+                    var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s/gim;
+                    var pathRegex = /\spath\s*=\s*('|")(.+?)\1/gim;
+                    var nameRegex = /\sname\s*=\s*('|")(.+?)\1/gim;
+                    var amdDependencyMatchResult = amdDependencyRegEx.exec(comment);
+                    if (amdDependencyMatchResult) {
+                        var pathMatchResult = pathRegex.exec(comment);
+                        var nameMatchResult = nameRegex.exec(comment);
+                        if (pathMatchResult) {
+                            var amdDependency = { path: pathMatchResult[2], name: nameMatchResult ? nameMatchResult[2] : undefined };
+                            amdDependencies.push(amdDependency);
+                        }
+                    }
+                    var checkJsDirectiveRegEx = /^\/\/\/?\s*(@ts-check|@ts-nocheck)\s*$/gim;
+                    var checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
+                    if (checkJsDirectiveMatchResult) {
+                        checkJsDirective = {
+                            enabled: ts.compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === 0 /* EqualTo */,
+                            end: range.end,
+                            pos: range.pos
+                        };
+                    }
+                }
+            }
+            sourceFile.referencedFiles = referencedFiles;
+            sourceFile.typeReferenceDirectives = typeReferenceDirectives;
+            sourceFile.amdDependencies = amdDependencies;
+            sourceFile.moduleName = amdModuleName;
+            sourceFile.checkJsDirective = checkJsDirective;
+        }
+        function setExternalModuleIndicator(sourceFile) {
+            sourceFile.externalModuleIndicator = ts.forEach(sourceFile.statements, function (node) {
+                return ts.hasModifier(node, 1 /* Export */)
+                    || node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 248 /* ExternalModuleReference */
+                    || node.kind === 238 /* ImportDeclaration */
+                    || node.kind === 243 /* ExportAssignment */
+                    || node.kind === 244 /* ExportDeclaration */
+                    ? node
+                    : undefined;
+            });
+        }
+        var ParsingContext;
+        (function (ParsingContext) {
+            ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
+            ParsingContext[ParsingContext["BlockStatements"] = 1] = "BlockStatements";
+            ParsingContext[ParsingContext["SwitchClauses"] = 2] = "SwitchClauses";
+            ParsingContext[ParsingContext["SwitchClauseStatements"] = 3] = "SwitchClauseStatements";
+            ParsingContext[ParsingContext["TypeMembers"] = 4] = "TypeMembers";
+            ParsingContext[ParsingContext["ClassMembers"] = 5] = "ClassMembers";
+            ParsingContext[ParsingContext["EnumMembers"] = 6] = "EnumMembers";
+            ParsingContext[ParsingContext["HeritageClauseElement"] = 7] = "HeritageClauseElement";
+            ParsingContext[ParsingContext["VariableDeclarations"] = 8] = "VariableDeclarations";
+            ParsingContext[ParsingContext["ObjectBindingElements"] = 9] = "ObjectBindingElements";
+            ParsingContext[ParsingContext["ArrayBindingElements"] = 10] = "ArrayBindingElements";
+            ParsingContext[ParsingContext["ArgumentExpressions"] = 11] = "ArgumentExpressions";
+            ParsingContext[ParsingContext["ObjectLiteralMembers"] = 12] = "ObjectLiteralMembers";
+            ParsingContext[ParsingContext["JsxAttributes"] = 13] = "JsxAttributes";
+            ParsingContext[ParsingContext["JsxChildren"] = 14] = "JsxChildren";
+            ParsingContext[ParsingContext["ArrayLiteralMembers"] = 15] = "ArrayLiteralMembers";
+            ParsingContext[ParsingContext["Parameters"] = 16] = "Parameters";
+            ParsingContext[ParsingContext["RestProperties"] = 17] = "RestProperties";
+            ParsingContext[ParsingContext["TypeParameters"] = 18] = "TypeParameters";
+            ParsingContext[ParsingContext["TypeArguments"] = 19] = "TypeArguments";
+            ParsingContext[ParsingContext["TupleElementTypes"] = 20] = "TupleElementTypes";
+            ParsingContext[ParsingContext["HeritageClauses"] = 21] = "HeritageClauses";
+            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 22] = "ImportOrExportSpecifiers";
+            ParsingContext[ParsingContext["Count"] = 23] = "Count"; // Number of parsing contexts
+        })(ParsingContext || (ParsingContext = {}));
+        var Tristate;
+        (function (Tristate) {
+            Tristate[Tristate["False"] = 0] = "False";
+            Tristate[Tristate["True"] = 1] = "True";
+            Tristate[Tristate["Unknown"] = 2] = "Unknown";
+        })(Tristate || (Tristate = {}));
+        var JSDocParser;
+        (function (JSDocParser) {
+            function parseJSDocTypeExpressionForTests(content, start, length) {
+                initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
+                sourceFile = createSourceFile("file.js", 5 /* Latest */, 1 /* JS */);
+                scanner.setText(content, start, length);
+                currentToken = scanner.scan();
+                var jsDocTypeExpression = parseJSDocTypeExpression();
+                var diagnostics = parseDiagnostics;
+                clearState();
+                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
+            }
+            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
+            function parseJSDocTypeExpression(requireBraces) {
+                var result = createNode(267 /* JSDocTypeExpression */, scanner.getTokenPos());
+                if (!parseExpected(17 /* OpenBraceToken */) && requireBraces) {
+                    return undefined;
+                }
+                result.type = doInsideOfContext(1048576 /* JSDoc */, parseType);
+                parseExpected(18 /* CloseBraceToken */);
+                fixupParentReferences(result);
+                return finishNode(result);
+            }
+            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
+            function parseIsolatedJSDocComment(content, start, length) {
+                initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
+                sourceFile = { languageVariant: 0 /* Standard */, text: content }; // tslint:disable-line no-object-literal-type-assertion
+                var jsDoc = parseJSDocCommentWorker(start, length);
+                var diagnostics = parseDiagnostics;
+                clearState();
+                return jsDoc ? { jsDoc: jsDoc, diagnostics: diagnostics } : undefined;
+            }
+            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
+            function parseJSDocComment(parent, start, length) {
+                var saveToken = currentToken;
+                var saveParseDiagnosticsLength = parseDiagnostics.length;
+                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
+                var comment = parseJSDocCommentWorker(start, length);
+                if (comment) {
+                    comment.parent = parent;
+                }
+                if (ts.isInJavaScriptFile(parent)) {
+                    if (!sourceFile.jsDocDiagnostics) {
+                        sourceFile.jsDocDiagnostics = [];
+                    }
+                    (_a = sourceFile.jsDocDiagnostics).push.apply(_a, parseDiagnostics);
+                }
+                currentToken = saveToken;
+                parseDiagnostics.length = saveParseDiagnosticsLength;
+                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
+                return comment;
+                var _a;
+            }
+            JSDocParser.parseJSDocComment = parseJSDocComment;
+            var JSDocState;
+            (function (JSDocState) {
+                JSDocState[JSDocState["BeginningOfLine"] = 0] = "BeginningOfLine";
+                JSDocState[JSDocState["SawAsterisk"] = 1] = "SawAsterisk";
+                JSDocState[JSDocState["SavingComments"] = 2] = "SavingComments";
+            })(JSDocState || (JSDocState = {}));
+            var PropertyLikeParse;
+            (function (PropertyLikeParse) {
+                PropertyLikeParse[PropertyLikeParse["Property"] = 0] = "Property";
+                PropertyLikeParse[PropertyLikeParse["Parameter"] = 1] = "Parameter";
+            })(PropertyLikeParse || (PropertyLikeParse = {}));
+            function parseJSDocCommentWorker(start, length) {
+                var content = sourceText;
+                start = start || 0;
+                var end = length === undefined ? content.length : start + length;
+                length = end - start;
+                ts.Debug.assert(start >= 0);
+                ts.Debug.assert(start <= end);
+                ts.Debug.assert(end <= content.length);
+                var tags;
+                var tagsPos;
+                var tagsEnd;
+                var comments = [];
+                var result;
+                // Check for /** (JSDoc opening part)
+                if (!isJsDocStart(content, start)) {
+                    return result;
+                }
+                // + 3 for leading /**, - 5 in total for /** */
+                scanner.scanRange(start + 3, length - 5, function () {
+                    // Initially we can parse out a tag.  We also have seen a starting asterisk.
+                    // This is so that /** * @type */ doesn't parse.
+                    var advanceToken = true;
+                    var state = 1 /* SawAsterisk */;
+                    var margin = undefined;
+                    // + 4 for leading '/** '
+                    var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4;
+                    function pushComment(text) {
+                        if (!margin) {
+                            margin = indent;
+                        }
+                        comments.push(text);
+                        indent += text.length;
+                    }
+                    nextJSDocToken();
+                    while (token() === 5 /* WhitespaceTrivia */) {
+                        nextJSDocToken();
+                    }
+                    if (token() === 4 /* NewLineTrivia */) {
+                        state = 0 /* BeginningOfLine */;
+                        indent = 0;
+                        nextJSDocToken();
+                    }
+                    while (token() !== 1 /* EndOfFileToken */) {
+                        switch (token()) {
+                            case 57 /* AtToken */:
+                                if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) {
+                                    removeTrailingNewlines(comments);
+                                    parseTag(indent);
+                                    // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
+                                    // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
+                                    // for malformed examples like `/** @param {string} x @returns {number} the length */`
+                                    state = 0 /* BeginningOfLine */;
+                                    advanceToken = false;
+                                    margin = undefined;
+                                    indent++;
+                                }
+                                else {
+                                    pushComment(scanner.getTokenText());
+                                }
+                                break;
+                            case 4 /* NewLineTrivia */:
+                                comments.push(scanner.getTokenText());
+                                state = 0 /* BeginningOfLine */;
+                                indent = 0;
+                                break;
+                            case 39 /* AsteriskToken */:
+                                var asterisk = scanner.getTokenText();
+                                if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) {
+                                    // If we've already seen an asterisk, then we can no longer parse a tag on this line
+                                    state = 2 /* SavingComments */;
+                                    pushComment(asterisk);
+                                }
+                                else {
+                                    // Ignore the first asterisk on a line
+                                    state = 1 /* SawAsterisk */;
+                                    indent += asterisk.length;
+                                }
+                                break;
+                            case 71 /* Identifier */:
+                                // Anything else is doc comment text. We just save it. Because it
+                                // wasn't a tag, we can no longer parse a tag on this line until we hit the next
+                                // line break.
+                                pushComment(scanner.getTokenText());
+                                state = 2 /* SavingComments */;
+                                break;
+                            case 5 /* WhitespaceTrivia */:
+                                // only collect whitespace if we're already saving comments or have just crossed the comment indent margin
+                                var whitespace = scanner.getTokenText();
+                                if (state === 2 /* SavingComments */) {
+                                    comments.push(whitespace);
+                                }
+                                else if (margin !== undefined && indent + whitespace.length > margin) {
+                                    comments.push(whitespace.slice(margin - indent - 1));
+                                }
+                                indent += whitespace.length;
+                                break;
+                            case 1 /* EndOfFileToken */:
+                                break;
+                            default:
+                                // anything other than whitespace or asterisk at the beginning of the line starts the comment text
+                                state = 2 /* SavingComments */;
+                                pushComment(scanner.getTokenText());
+                                break;
+                        }
+                        if (advanceToken) {
+                            nextJSDocToken();
+                        }
+                        else {
+                            advanceToken = true;
+                        }
+                    }
+                    removeLeadingNewlines(comments);
+                    removeTrailingNewlines(comments);
+                    result = createJSDocComment();
+                });
+                return result;
+                function removeLeadingNewlines(comments) {
+                    while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) {
+                        comments.shift();
+                    }
+                }
+                function removeTrailingNewlines(comments) {
+                    while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) {
+                        comments.pop();
+                    }
+                }
+                function isJsDocStart(content, start) {
+                    return content.charCodeAt(start) === 47 /* slash */ &&
+                        content.charCodeAt(start + 1) === 42 /* asterisk */ &&
+                        content.charCodeAt(start + 2) === 42 /* asterisk */ &&
+                        content.charCodeAt(start + 3) !== 42 /* asterisk */;
+                }
+                function createJSDocComment() {
+                    var result = createNode(275 /* JSDocComment */, start);
+                    result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
+                    result.comment = comments.length ? comments.join("") : undefined;
+                    return finishNode(result, end);
+                }
+                function skipWhitespace() {
+                    while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
+                        nextJSDocToken();
+                    }
+                }
+                function parseTag(indent) {
+                    ts.Debug.assert(token() === 57 /* AtToken */);
+                    var atToken = createNode(57 /* AtToken */, scanner.getTokenPos());
+                    atToken.end = scanner.getTextPos();
+                    nextJSDocToken();
+                    var tagName = parseJSDocIdentifierName();
+                    skipWhitespace();
+                    if (!tagName) {
+                        return;
+                    }
+                    var tag;
+                    if (tagName) {
+                        switch (tagName.escapedText) {
+                            case "augments":
+                            case "extends":
+                                tag = parseAugmentsTag(atToken, tagName);
+                                break;
+                            case "class":
+                            case "constructor":
+                                tag = parseClassTag(atToken, tagName);
+                                break;
+                            case "arg":
+                            case "argument":
+                            case "param":
+                                tag = parseParameterOrPropertyTag(atToken, tagName, 1 /* Parameter */);
+                                break;
+                            case "return":
+                            case "returns":
+                                tag = parseReturnTag(atToken, tagName);
+                                break;
+                            case "template":
+                                tag = parseTemplateTag(atToken, tagName);
+                                break;
+                            case "type":
+                                tag = parseTypeTag(atToken, tagName);
+                                break;
+                            case "typedef":
+                                tag = parseTypedefTag(atToken, tagName);
+                                break;
+                            default:
+                                tag = parseUnknownTag(atToken, tagName);
+                                break;
+                        }
+                    }
+                    else {
+                        tag = parseUnknownTag(atToken, tagName);
+                    }
+                    if (!tag) {
+                        // a badly malformed tag should not be added to the list of tags
+                        return;
+                    }
+                    addTag(tag, parseTagComments(indent + tag.end - tag.pos));
+                }
+                function parseTagComments(indent) {
+                    var comments = [];
+                    var state = 0 /* BeginningOfLine */;
+                    var margin;
+                    function pushComment(text) {
+                        if (!margin) {
+                            margin = indent;
+                        }
+                        comments.push(text);
+                        indent += text.length;
+                    }
+                    while (token() !== 57 /* AtToken */ && token() !== 1 /* EndOfFileToken */) {
+                        switch (token()) {
+                            case 4 /* NewLineTrivia */:
+                                if (state >= 1 /* SawAsterisk */) {
+                                    state = 0 /* BeginningOfLine */;
+                                    comments.push(scanner.getTokenText());
+                                }
+                                indent = 0;
+                                break;
+                            case 57 /* AtToken */:
+                                // Done
+                                break;
+                            case 5 /* WhitespaceTrivia */:
+                                if (state === 2 /* SavingComments */) {
+                                    pushComment(scanner.getTokenText());
+                                }
+                                else {
+                                    var whitespace = scanner.getTokenText();
+                                    // if the whitespace crosses the margin, take only the whitespace that passes the margin
+                                    if (margin !== undefined && indent + whitespace.length > margin) {
+                                        comments.push(whitespace.slice(margin - indent - 1));
+                                    }
+                                    indent += whitespace.length;
+                                }
+                                break;
+                            case 39 /* AsteriskToken */:
+                                if (state === 0 /* BeginningOfLine */) {
+                                    // leading asterisks start recording on the *next* (non-whitespace) token
+                                    state = 1 /* SawAsterisk */;
+                                    indent += scanner.getTokenText().length;
+                                    break;
+                                }
+                            // record the * as a comment
+                            // falls through
+                            default:
+                                state = 2 /* SavingComments */; // leading identifiers start recording as well
+                                pushComment(scanner.getTokenText());
+                                break;
+                        }
+                        if (token() === 57 /* AtToken */) {
+                            // Done
+                            break;
+                        }
+                        nextJSDocToken();
+                    }
+                    removeLeadingNewlines(comments);
+                    removeTrailingNewlines(comments);
+                    return comments;
+                }
+                function parseUnknownTag(atToken, tagName) {
+                    var result = createNode(276 /* JSDocTag */, atToken.pos);
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    return finishNode(result);
+                }
+                function addTag(tag, comments) {
+                    tag.comment = comments.join("");
+                    if (!tags) {
+                        tags = [tag];
+                        tagsPos = tag.pos;
+                    }
+                    else {
+                        tags.push(tag);
+                    }
+                    tagsEnd = tag.end;
+                }
+                function tryParseTypeExpression() {
+                    skipWhitespace();
+                    return token() === 17 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined;
+                }
+                function parseBracketNameInPropertyAndParamTag() {
+                    // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
+                    var isBracketed = parseOptional(21 /* OpenBracketToken */);
+                    var name = parseJSDocEntityName();
+                    if (isBracketed) {
+                        skipWhitespace();
+                        // May have an optional default, e.g. '[foo = 42]'
+                        if (parseOptionalToken(58 /* EqualsToken */)) {
+                            parseExpression();
+                        }
+                        parseExpected(22 /* CloseBracketToken */);
+                    }
+                    return { name: name, isBracketed: isBracketed };
+                }
+                function isObjectOrObjectArrayTypeReference(node) {
+                    switch (node.kind) {
+                        case 134 /* ObjectKeyword */:
+                            return true;
+                        case 164 /* ArrayType */:
+                            return isObjectOrObjectArrayTypeReference(node.elementType);
+                        default:
+                            return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object";
+                    }
+                }
+                function parseParameterOrPropertyTag(atToken, tagName, target) {
+                    var typeExpression = tryParseTypeExpression();
+                    var isNameFirst = !typeExpression;
+                    skipWhitespace();
+                    var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed;
+                    skipWhitespace();
+                    if (isNameFirst) {
+                        typeExpression = tryParseTypeExpression();
+                    }
+                    var result = target === 1 /* Parameter */ ?
+                        createNode(279 /* JSDocParameterTag */, atToken.pos) :
+                        createNode(284 /* JSDocPropertyTag */, atToken.pos);
+                    var nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name);
+                    if (nestedTypeLiteral) {
+                        typeExpression = nestedTypeLiteral;
+                        isNameFirst = true;
+                    }
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    result.typeExpression = typeExpression;
+                    result.name = name;
+                    result.isNameFirst = isNameFirst;
+                    result.isBracketed = isBracketed;
+                    return finishNode(result);
+                }
+                function parseNestedTypeLiteral(typeExpression, name) {
+                    if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
+                        var typeLiteralExpression = createNode(267 /* JSDocTypeExpression */, scanner.getTokenPos());
+                        var child = void 0;
+                        var jsdocTypeLiteral = void 0;
+                        var start_2 = scanner.getStartPos();
+                        var children = void 0;
+                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(1 /* Parameter */, name); })) {
+                            if (!children) {
+                                children = [];
+                            }
+                            children.push(child);
+                        }
+                        if (children) {
+                            jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_2);
+                            jsdocTypeLiteral.jsDocPropertyTags = children;
+                            if (typeExpression.type.kind === 164 /* ArrayType */) {
+                                jsdocTypeLiteral.isArrayType = true;
+                            }
+                            typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
+                            return finishNode(typeLiteralExpression);
+                        }
+                    }
+                }
+                function parseReturnTag(atToken, tagName) {
+                    if (ts.forEach(tags, function (t) { return t.kind === 280 /* JSDocReturnTag */; })) {
+                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
+                    }
+                    var result = createNode(280 /* JSDocReturnTag */, atToken.pos);
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    result.typeExpression = tryParseTypeExpression();
+                    return finishNode(result);
+                }
+                function parseTypeTag(atToken, tagName) {
+                    if (ts.forEach(tags, function (t) { return t.kind === 281 /* JSDocTypeTag */; })) {
+                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
+                    }
+                    var result = createNode(281 /* JSDocTypeTag */, atToken.pos);
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    result.typeExpression = parseJSDocTypeExpression(/*requireBraces*/ true);
+                    return finishNode(result);
+                }
+                function parseAugmentsTag(atToken, tagName) {
+                    var result = createNode(277 /* JSDocAugmentsTag */, atToken.pos);
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    result.class = parseExpressionWithTypeArgumentsForAugments();
+                    return finishNode(result);
+                }
+                function parseExpressionWithTypeArgumentsForAugments() {
+                    var usedBrace = parseOptional(17 /* OpenBraceToken */);
+                    var node = createNode(201 /* ExpressionWithTypeArguments */);
+                    node.expression = parsePropertyAccessEntityNameExpression();
+                    node.typeArguments = tryParseTypeArguments();
+                    var res = finishNode(node);
+                    if (usedBrace) {
+                        parseExpected(18 /* CloseBraceToken */);
+                    }
+                    return res;
+                }
+                function parsePropertyAccessEntityNameExpression() {
+                    var node = parseJSDocIdentifierName(/*createIfMissing*/ true);
+                    while (parseOptional(23 /* DotToken */)) {
+                        var prop = createNode(179 /* PropertyAccessExpression */, node.pos);
+                        prop.expression = node;
+                        prop.name = parseJSDocIdentifierName();
+                        node = finishNode(prop);
+                    }
+                    return node;
+                }
+                function parseClassTag(atToken, tagName) {
+                    var tag = createNode(278 /* JSDocClassTag */, atToken.pos);
+                    tag.atToken = atToken;
+                    tag.tagName = tagName;
+                    return finishNode(tag);
+                }
+                function parseTypedefTag(atToken, tagName) {
+                    var typeExpression = tryParseTypeExpression();
+                    skipWhitespace();
+                    var typedefTag = createNode(283 /* JSDocTypedefTag */, atToken.pos);
+                    typedefTag.atToken = atToken;
+                    typedefTag.tagName = tagName;
+                    typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
+                    if (typedefTag.fullName) {
+                        var rightNode = typedefTag.fullName;
+                        while (true) {
+                            if (rightNode.kind === 71 /* Identifier */ || !rightNode.body) {
+                                // if node is identifier - use it as name
+                                // otherwise use name of the rightmost part that we were able to parse
+                                typedefTag.name = rightNode.kind === 71 /* Identifier */ ? rightNode : rightNode.name;
+                                break;
+                            }
+                            rightNode = rightNode.body;
+                        }
+                    }
+                    skipWhitespace();
+                    typedefTag.typeExpression = typeExpression;
+                    if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
+                        var child = void 0;
+                        var jsdocTypeLiteral = void 0;
+                        var childTypeTag = void 0;
+                        var start_3 = scanner.getStartPos();
+                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0 /* Property */); })) {
+                            if (!jsdocTypeLiteral) {
+                                jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_3);
+                            }
+                            if (child.kind === 281 /* JSDocTypeTag */) {
+                                if (childTypeTag) {
+                                    break;
+                                }
+                                else {
+                                    childTypeTag = child;
+                                }
+                            }
+                            else {
+                                if (!jsdocTypeLiteral.jsDocPropertyTags) {
+                                    jsdocTypeLiteral.jsDocPropertyTags = [];
+                                }
+                                jsdocTypeLiteral.jsDocPropertyTags.push(child);
+                            }
+                        }
+                        if (jsdocTypeLiteral) {
+                            if (typeExpression && typeExpression.type.kind === 164 /* ArrayType */) {
+                                jsdocTypeLiteral.isArrayType = true;
+                            }
+                            typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
+                                childTypeTag.typeExpression :
+                                finishNode(jsdocTypeLiteral);
+                        }
+                    }
+                    return finishNode(typedefTag);
+                    function parseJSDocTypeNameWithNamespace(flags) {
+                        var pos = scanner.getTokenPos();
+                        var typeNameOrNamespaceName = parseJSDocIdentifierName();
+                        if (typeNameOrNamespaceName && parseOptional(23 /* DotToken */)) {
+                            var jsDocNamespaceNode = createNode(233 /* ModuleDeclaration */, pos);
+                            jsDocNamespaceNode.flags |= flags;
+                            jsDocNamespaceNode.name = typeNameOrNamespaceName;
+                            jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(4 /* NestedNamespace */);
+                            return finishNode(jsDocNamespaceNode);
+                        }
+                        if (typeNameOrNamespaceName && flags & 4 /* NestedNamespace */) {
+                            typeNameOrNamespaceName.isInJSDocNamespace = true;
+                        }
+                        return typeNameOrNamespaceName;
+                    }
+                }
+                function escapedTextsEqual(a, b) {
+                    while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
+                        if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
+                            a = a.left;
+                            b = b.left;
+                        }
+                        else {
+                            return false;
+                        }
+                    }
+                    return a.escapedText === b.escapedText;
+                }
+                function parseChildParameterOrPropertyTag(target, name) {
+                    var canParseTag = true;
+                    var seenAsterisk = false;
+                    while (true) {
+                        nextJSDocToken();
+                        switch (token()) {
+                            case 57 /* AtToken */:
+                                if (canParseTag) {
+                                    var child = tryParseChildTag(target);
+                                    if (child && child.kind === 279 /* JSDocParameterTag */ &&
+                                        (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
+                                        return false;
+                                    }
+                                    return child;
+                                }
+                                seenAsterisk = false;
+                                break;
+                            case 4 /* NewLineTrivia */:
+                                canParseTag = true;
+                                seenAsterisk = false;
+                                break;
+                            case 39 /* AsteriskToken */:
+                                if (seenAsterisk) {
+                                    canParseTag = false;
+                                }
+                                seenAsterisk = true;
+                                break;
+                            case 71 /* Identifier */:
+                                canParseTag = false;
+                                break;
+                            case 1 /* EndOfFileToken */:
+                                return false;
+                        }
+                    }
+                }
+                function tryParseChildTag(target) {
+                    ts.Debug.assert(token() === 57 /* AtToken */);
+                    var atToken = createNode(57 /* AtToken */, scanner.getStartPos());
+                    atToken.end = scanner.getTextPos();
+                    nextJSDocToken();
+                    var tagName = parseJSDocIdentifierName();
+                    skipWhitespace();
+                    if (!tagName) {
+                        return false;
+                    }
+                    switch (tagName.escapedText) {
+                        case "type":
+                            return target === 0 /* Property */ && parseTypeTag(atToken, tagName);
+                        case "prop":
+                        case "property":
+                            return target === 0 /* Property */ && parseParameterOrPropertyTag(atToken, tagName, target);
+                        case "arg":
+                        case "argument":
+                        case "param":
+                            return target === 1 /* Parameter */ && parseParameterOrPropertyTag(atToken, tagName, target);
+                    }
+                    return false;
+                }
+                function parseTemplateTag(atToken, tagName) {
+                    if (ts.forEach(tags, function (t) { return t.kind === 282 /* JSDocTemplateTag */; })) {
+                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
+                    }
+                    // Type parameter list looks like '@template T,U,V'
+                    var typeParameters = [];
+                    var typeParametersPos = getNodePos();
+                    while (true) {
+                        var name = parseJSDocIdentifierName();
+                        skipWhitespace();
+                        if (!name) {
+                            parseErrorAtPosition(scanner.getStartPos(), 0, ts.Diagnostics.Identifier_expected);
+                            return undefined;
+                        }
+                        var typeParameter = createNode(145 /* TypeParameter */, name.pos);
+                        typeParameter.name = name;
+                        finishNode(typeParameter);
+                        typeParameters.push(typeParameter);
+                        if (token() === 26 /* CommaToken */) {
+                            nextJSDocToken();
+                            skipWhitespace();
+                        }
+                        else {
+                            break;
+                        }
+                    }
+                    var result = createNode(282 /* JSDocTemplateTag */, atToken.pos);
+                    result.atToken = atToken;
+                    result.tagName = tagName;
+                    result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
+                    finishNode(result);
+                    return result;
+                }
+                function nextJSDocToken() {
+                    return currentToken = scanner.scanJSDocToken();
+                }
+                function parseJSDocEntityName() {
+                    var entity = parseJSDocIdentifierName(/*createIfMissing*/ true);
+                    if (parseOptional(21 /* OpenBracketToken */)) {
+                        parseExpected(22 /* CloseBracketToken */);
+                        // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
+                        // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
+                        // but it's not worth it to enforce that restriction.
+                    }
+                    while (parseOptional(23 /* DotToken */)) {
+                        var name = parseJSDocIdentifierName(/*createIfMissing*/ true);
+                        if (parseOptional(21 /* OpenBracketToken */)) {
+                            parseExpected(22 /* CloseBracketToken */);
+                        }
+                        entity = createQualifiedName(entity, name);
+                    }
+                    return entity;
+                }
+                function parseJSDocIdentifierName(createIfMissing) {
+                    if (createIfMissing === void 0) { createIfMissing = false; }
+                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
+                        if (createIfMissing) {
+                            return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
+                        }
+                        else {
+                            parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected);
+                            return undefined;
+                        }
+                    }
+                    var pos = scanner.getTokenPos();
+                    var end = scanner.getTextPos();
+                    var result = createNode(71 /* Identifier */, pos);
+                    result.escapedText = ts.escapeLeadingUnderscores(content.substring(pos, end));
+                    finishNode(result, end);
+                    nextJSDocToken();
+                    return result;
+                }
+            }
+            JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
+        })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
+    })(Parser || (Parser = {}));
+    var IncrementalParser;
+    (function (IncrementalParser) {
+        function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
+            aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
+            checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
+            if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
+                // if the text didn't change, then we can just return our current source file as-is.
+                return sourceFile;
+            }
+            if (sourceFile.statements.length === 0) {
+                // If we don't have any statements in the current source file, then there's no real
+                // way to incrementally parse.  So just do a full parse instead.
+                return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind);
+            }
+            // Make sure we're not trying to incrementally update a source file more than once.  Once
+            // we do an update the original source file is considered unusable from that point onwards.
+            //
+            // This is because we do incremental parsing in-place.  i.e. we take nodes from the old
+            // tree and give them new positions and parents.  From that point on, trusting the old
+            // tree at all is not possible as far too much of it may violate invariants.
+            var incrementalSourceFile = sourceFile;
+            ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
+            incrementalSourceFile.hasBeenIncrementallyParsed = true;
+            var oldText = sourceFile.text;
+            var syntaxCursor = createSyntaxCursor(sourceFile);
+            // Make the actual change larger so that we know to reparse anything whose lookahead
+            // might have intersected the change.
+            var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
+            checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
+            // Ensure that extending the affected range only moved the start of the change range
+            // earlier in the file.
+            ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
+            ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
+            ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
+            // The is the amount the nodes after the edit range need to be adjusted.  It can be
+            // positive (if the edit added characters), negative (if the edit deleted characters)
+            // or zero (if this was a pure overwrite with nothing added/removed).
+            var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
+            // If we added or removed characters during the edit, then we need to go and adjust all
+            // the nodes after the edit.  Those nodes may move forward (if we inserted chars) or they
+            // may move backward (if we deleted chars).
+            //
+            // Doing this helps us out in two ways.  First, it means that any nodes/tokens we want
+            // to reuse are already at the appropriate position in the new text.  That way when we
+            // reuse them, we don't have to figure out if they need to be adjusted.  Second, it makes
+            // it very easy to determine if we can reuse a node.  If the node's position is at where
+            // we are in the text, then we can reuse it.  Otherwise we can't.  If the node's position
+            // is ahead of us, then we'll need to rescan tokens.  If the node's position is behind
+            // us, then we'll need to skip it or crumble it as appropriate
+            //
+            // We will also adjust the positions of nodes that intersect the change range as well.
+            // By doing this, we ensure that all the positions in the old tree are consistent, not
+            // just the positions of nodes entirely before/after the change range.  By being
+            // consistent, we can then easily map from positions to nodes in the old tree easily.
+            //
+            // Also, mark any syntax elements that intersect the changed span.  We know, up front,
+            // that we cannot reuse these elements.
+            updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
+            // Now that we've set up our internal incremental state just proceed and parse the
+            // source file in the normal fashion.  When possible the parser will retrieve and
+            // reuse nodes from the old tree.
+            //
+            // Note: passing in 'true' for setNodeParents is very important.  When incrementally
+            // parsing, we will be reusing nodes from the old tree, and placing it into new
+            // parents.  If we don't set the parents now, we'll end up with an observably
+            // inconsistent tree.  Setting the parents on the new tree should be very fast.  We
+            // will immediately bail out of walking any subtrees when we can see that their parents
+            // are already correct.
+            var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind);
+            return result;
+        }
+        IncrementalParser.updateSourceFile = updateSourceFile;
+        function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
+            if (isArray) {
+                visitArray(element);
+            }
+            else {
+                visitNode(element);
+            }
+            return;
+            function visitNode(node) {
+                var text = "";
+                if (aggressiveChecks && shouldCheckNode(node)) {
+                    text = oldText.substring(node.pos, node.end);
+                }
+                // Ditch any existing LS children we may have created.  This way we can avoid
+                // moving them forward.
+                if (node._children) {
+                    node._children = undefined;
+                }
+                node.pos += delta;
+                node.end += delta;
+                if (aggressiveChecks && shouldCheckNode(node)) {
+                    ts.Debug.assert(text === newText.substring(node.pos, node.end));
+                }
+                forEachChild(node, visitNode, visitArray);
+                if (ts.hasJSDocNodes(node)) {
+                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
+                        var jsDocComment = _a[_i];
+                        forEachChild(jsDocComment, visitNode, visitArray);
+                    }
+                }
+                checkNodePositions(node, aggressiveChecks);
+            }
+            function visitArray(array) {
+                array._children = undefined;
+                array.pos += delta;
+                array.end += delta;
+                for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
+                    var node = array_8[_i];
+                    visitNode(node);
+                }
+            }
+        }
+        function shouldCheckNode(node) {
+            switch (node.kind) {
+                case 9 /* StringLiteral */:
+                case 8 /* NumericLiteral */:
+                case 71 /* Identifier */:
+                    return true;
+            }
+            return false;
+        }
+        function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
+            ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
+            ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
+            ts.Debug.assert(element.pos <= element.end);
+            // We have an element that intersects the change range in some way.  It may have its
+            // start, or its end (or both) in the changed range.  We want to adjust any part
+            // that intersects such that the final tree is in a consistent state.  i.e. all
+            // children have spans within the span of their parent, and all siblings are ordered
+            // properly.
+            // We may need to update both the 'pos' and the 'end' of the element.
+            // If the 'pos' is before the start of the change, then we don't need to touch it.
+            // If it isn't, then the 'pos' must be inside the change.  How we update it will
+            // depend if delta is  positive or negative.  If delta is positive then we have
+            // something like:
+            //
+            //  -------------------AAA-----------------
+            //  -------------------BBBCCCCCCC-----------------
+            //
+            // In this case, we consider any node that started in the change range to still be
+            // starting at the same position.
+            //
+            // however, if the delta is negative, then we instead have something like this:
+            //
+            //  -------------------XXXYYYYYYY-----------------
+            //  -------------------ZZZ-----------------
+            //
+            // In this case, any element that started in the 'X' range will keep its position.
+            // However any element that started after that will have their pos adjusted to be
+            // at the end of the new range.  i.e. any node that started in the 'Y' range will
+            // be adjusted to have their start at the end of the 'Z' range.
+            //
+            // The element will keep its position if possible.  Or Move backward to the new-end
+            // if it's in the 'Y' range.
+            element.pos = Math.min(element.pos, changeRangeNewEnd);
+            // If the 'end' is after the change range, then we always adjust it by the delta
+            // amount.  However, if the end is in the change range, then how we adjust it
+            // will depend on if delta is  positive or negative.  If delta is positive then we
+            // have something like:
+            //
+            //  -------------------AAA-----------------
+            //  -------------------BBBCCCCCCC-----------------
+            //
+            // In this case, we consider any node that ended inside the change range to keep its
+            // end position.
+            //
+            // however, if the delta is negative, then we instead have something like this:
+            //
+            //  -------------------XXXYYYYYYY-----------------
+            //  -------------------ZZZ-----------------
+            //
+            // In this case, any element that ended in the 'X' range will keep its position.
+            // However any element that ended after that will have their pos adjusted to be
+            // at the end of the new range.  i.e. any node that ended in the 'Y' range will
+            // be adjusted to have their end at the end of the 'Z' range.
+            if (element.end >= changeRangeOldEnd) {
+                // Element ends after the change range.  Always adjust the end pos.
+                element.end += delta;
+            }
+            else {
+                // Element ends in the change range.  The element will keep its position if
+                // possible. Or Move backward to the new-end if it's in the 'Y' range.
+                element.end = Math.min(element.end, changeRangeNewEnd);
+            }
+            ts.Debug.assert(element.pos <= element.end);
+            if (element.parent) {
+                ts.Debug.assert(element.pos >= element.parent.pos);
+                ts.Debug.assert(element.end <= element.parent.end);
+            }
+        }
+        function checkNodePositions(node, aggressiveChecks) {
+            if (aggressiveChecks) {
+                var pos_2 = node.pos;
+                forEachChild(node, function (child) {
+                    ts.Debug.assert(child.pos >= pos_2);
+                    pos_2 = child.end;
+                });
+                ts.Debug.assert(pos_2 <= node.end);
+            }
+        }
+        function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
+            visitNode(sourceFile);
+            return;
+            function visitNode(child) {
+                ts.Debug.assert(child.pos <= child.end);
+                if (child.pos > changeRangeOldEnd) {
+                    // Node is entirely past the change range.  We need to move both its pos and
+                    // end, forward or backward appropriately.
+                    moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
+                    return;
+                }
+                // Check if the element intersects the change range.  If it does, then it is not
+                // reusable.  Also, we'll need to recurse to see what constituent portions we may
+                // be able to use.
+                var fullEnd = child.end;
+                if (fullEnd >= changeStart) {
+                    child.intersectsChange = true;
+                    child._children = undefined;
+                    // Adjust the pos or end (or both) of the intersecting element accordingly.
+                    adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+                    forEachChild(child, visitNode, visitArray);
+                    checkNodePositions(child, aggressiveChecks);
+                    return;
+                }
+                // Otherwise, the node is entirely before the change range.  No need to do anything with it.
+                ts.Debug.assert(fullEnd < changeStart);
+            }
+            function visitArray(array) {
+                ts.Debug.assert(array.pos <= array.end);
+                if (array.pos > changeRangeOldEnd) {
+                    // Array is entirely after the change range.  We need to move it, and move any of
+                    // its children.
+                    moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
+                    return;
+                }
+                // Check if the element intersects the change range.  If it does, then it is not
+                // reusable.  Also, we'll need to recurse to see what constituent portions we may
+                // be able to use.
+                var fullEnd = array.end;
+                if (fullEnd >= changeStart) {
+                    array.intersectsChange = true;
+                    array._children = undefined;
+                    // Adjust the pos or end (or both) of the intersecting array accordingly.
+                    adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+                    for (var _i = 0, array_9 = array; _i < array_9.length; _i++) {
+                        var node = array_9[_i];
+                        visitNode(node);
+                    }
+                    return;
+                }
+                // Otherwise, the array is entirely before the change range.  No need to do anything with it.
+                ts.Debug.assert(fullEnd < changeStart);
+            }
+        }
+        function extendToAffectedRange(sourceFile, changeRange) {
+            // Consider the following code:
+            //      void foo() { /; }
+            //
+            // If the text changes with an insertion of / just before the semicolon then we end up with:
+            //      void foo() { //; }
+            //
+            // If we were to just use the changeRange a is, then we would not rescan the { token
+            // (as it does not intersect the actual original change range).  Because an edit may
+            // change the token touching it, we actually need to look back *at least* one token so
+            // that the prior token sees that change.
+            var maxLookahead = 1;
+            var start = changeRange.span.start;
+            // the first iteration aligns us with the change start. subsequent iteration move us to
+            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
+            // start of the tree.
+            for (var i = 0; start > 0 && i <= maxLookahead; i++) {
+                var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
+                ts.Debug.assert(nearestNode.pos <= start);
+                var position = nearestNode.pos;
+                start = Math.max(0, position - 1);
+            }
+            var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
+            var finalLength = changeRange.newLength + (changeRange.span.start - start);
+            return ts.createTextChangeRange(finalSpan, finalLength);
+        }
+        function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
+            var bestResult = sourceFile;
+            var lastNodeEntirelyBeforePosition;
+            forEachChild(sourceFile, visit);
+            if (lastNodeEntirelyBeforePosition) {
+                var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
+                if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
+                    bestResult = lastChildOfLastEntireNodeBeforePosition;
+                }
+            }
+            return bestResult;
+            function getLastChild(node) {
+                while (true) {
+                    var lastChild = getLastChildWorker(node);
+                    if (lastChild) {
+                        node = lastChild;
+                    }
+                    else {
+                        return node;
+                    }
+                }
+            }
+            function getLastChildWorker(node) {
+                var last = undefined;
+                forEachChild(node, function (child) {
+                    if (ts.nodeIsPresent(child)) {
+                        last = child;
+                    }
+                });
+                return last;
+            }
+            function visit(child) {
+                if (ts.nodeIsMissing(child)) {
+                    // Missing nodes are effectively invisible to us.  We never even consider them
+                    // When trying to find the nearest node before us.
+                    return;
+                }
+                // If the child intersects this position, then this node is currently the nearest
+                // node that starts before the position.
+                if (child.pos <= position) {
+                    if (child.pos >= bestResult.pos) {
+                        // This node starts before the position, and is closer to the position than
+                        // the previous best node we found.  It is now the new best node.
+                        bestResult = child;
+                    }
+                    // Now, the node may overlap the position, or it may end entirely before the
+                    // position.  If it overlaps with the position, then either it, or one of its
+                    // children must be the nearest node before the position.  So we can just
+                    // recurse into this child to see if we can find something better.
+                    if (position < child.end) {
+                        // The nearest node is either this child, or one of the children inside
+                        // of it.  We've already marked this child as the best so far.  Recurse
+                        // in case one of the children is better.
+                        forEachChild(child, visit);
+                        // Once we look at the children of this node, then there's no need to
+                        // continue any further.
+                        return true;
+                    }
+                    else {
+                        ts.Debug.assert(child.end <= position);
+                        // The child ends entirely before this position.  Say you have the following
+                        // (where $ is the position)
+                        //
+                        //      <complex expr 1> ? <complex expr 2> $ : <...> <...>
+                        //
+                        // We would want to find the nearest preceding node in "complex expr 2".
+                        // To support that, we keep track of this node, and once we're done searching
+                        // for a best node, we recurse down this node to see if we can find a good
+                        // result in it.
+                        //
+                        // This approach allows us to quickly skip over nodes that are entirely
+                        // before the position, while still allowing us to find any nodes in the
+                        // last one that might be what we want.
+                        lastNodeEntirelyBeforePosition = child;
+                    }
+                }
+                else {
+                    ts.Debug.assert(child.pos > position);
+                    // We're now at a node that is entirely past the position we're searching for.
+                    // This node (and all following nodes) could never contribute to the result,
+                    // so just skip them by returning 'true' here.
+                    return true;
+                }
+            }
+        }
+        function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
+            var oldText = sourceFile.text;
+            if (textChangeRange) {
+                ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
+                if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
+                    var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
+                    var newTextPrefix = newText.substr(0, textChangeRange.span.start);
+                    ts.Debug.assert(oldTextPrefix === newTextPrefix);
+                    var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
+                    var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
+                    ts.Debug.assert(oldTextSuffix === newTextSuffix);
+                }
+            }
+        }
+        function createSyntaxCursor(sourceFile) {
+            var currentArray = sourceFile.statements;
+            var currentArrayIndex = 0;
+            ts.Debug.assert(currentArrayIndex < currentArray.length);
+            var current = currentArray[currentArrayIndex];
+            var lastQueriedPosition = -1 /* Value */;
+            return {
+                currentNode: function (position) {
+                    // Only compute the current node if the position is different than the last time
+                    // we were asked.  The parser commonly asks for the node at the same position
+                    // twice.  Once to know if can read an appropriate list element at a certain point,
+                    // and then to actually read and consume the node.
+                    if (position !== lastQueriedPosition) {
+                        // Much of the time the parser will need the very next node in the array that
+                        // we just returned a node from.So just simply check for that case and move
+                        // forward in the array instead of searching for the node again.
+                        if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
+                            currentArrayIndex++;
+                            current = currentArray[currentArrayIndex];
+                        }
+                        // If we don't have a node, or the node we have isn't in the right position,
+                        // then try to find a viable node at the position requested.
+                        if (!current || current.pos !== position) {
+                            findHighestListElementThatStartsAtPosition(position);
+                        }
+                    }
+                    // Cache this query so that we don't do any extra work if the parser calls back
+                    // into us.  Note: this is very common as the parser will make pairs of calls like
+                    // 'isListElement -> parseListElement'.  If we were unable to find a node when
+                    // called with 'isListElement', we don't want to redo the work when parseListElement
+                    // is called immediately after.
+                    lastQueriedPosition = position;
+                    // Either we don'd have a node, or we have a node at the position being asked for.
+                    ts.Debug.assert(!current || current.pos === position);
+                    return current;
+                }
+            };
+            // Finds the highest element in the tree we can find that starts at the provided position.
+            // The element must be a direct child of some node list in the tree.  This way after we
+            // return it, we can easily return its next sibling in the list.
+            function findHighestListElementThatStartsAtPosition(position) {
+                // Clear out any cached state about the last node we found.
+                currentArray = undefined;
+                currentArrayIndex = -1 /* Value */;
+                current = undefined;
+                // Recurse into the source file to find the highest node at this position.
+                forEachChild(sourceFile, visitNode, visitArray);
+                return;
+                function visitNode(node) {
+                    if (position >= node.pos && position < node.end) {
+                        // Position was within this node.  Keep searching deeper to find the node.
+                        forEachChild(node, visitNode, visitArray);
+                        // don't proceed any further in the search.
+                        return true;
+                    }
+                    // position wasn't in this node, have to keep searching.
+                    return false;
+                }
+                function visitArray(array) {
+                    if (position >= array.pos && position < array.end) {
+                        // position was in this array.  Search through this array to see if we find a
+                        // viable element.
+                        for (var i = 0; i < array.length; i++) {
+                            var child = array[i];
+                            if (child) {
+                                if (child.pos === position) {
+                                    // Found the right node.  We're done.
+                                    currentArray = array;
+                                    currentArrayIndex = i;
+                                    current = child;
+                                    return true;
+                                }
+                                else {
+                                    if (child.pos < position && position < child.end) {
+                                        // Position in somewhere within this child.  Search in it and
+                                        // stop searching in this array.
+                                        forEachChild(child, visitNode, visitArray);
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    // position wasn't in this array, have to keep searching.
+                    return false;
+                }
+            }
+        }
+        var InvalidPosition;
+        (function (InvalidPosition) {
+            InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
+        })(InvalidPosition || (InvalidPosition = {}));
+    })(IncrementalParser || (IncrementalParser = {}));
+})(ts || (ts = {}));
+/// <reference path="utilities.ts"/>
+/// <reference path="parser.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    var ModuleInstanceState;
+    (function (ModuleInstanceState) {
+        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
+        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
+        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
+    })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
+    function getModuleInstanceState(node) {
+        // A module is uninstantiated if it contains only
+        // 1. interface declarations, type alias declarations
+        if (node.kind === 230 /* InterfaceDeclaration */ || node.kind === 231 /* TypeAliasDeclaration */) {
+            return 0 /* NonInstantiated */;
+        }
+        else if (ts.isConstEnumDeclaration(node)) {
+            return 2 /* ConstEnumOnly */;
+        }
+        else if ((node.kind === 238 /* ImportDeclaration */ || node.kind === 237 /* ImportEqualsDeclaration */) && !(ts.hasModifier(node, 1 /* Export */))) {
+            return 0 /* NonInstantiated */;
+        }
+        else if (node.kind === 234 /* ModuleBlock */) {
+            var state_1 = 0 /* NonInstantiated */;
+            ts.forEachChild(node, function (n) {
+                switch (getModuleInstanceState(n)) {
+                    case 0 /* NonInstantiated */:
+                        // child is non-instantiated - continue searching
+                        return false;
+                    case 2 /* ConstEnumOnly */:
+                        // child is const enum only - record state and continue searching
+                        state_1 = 2 /* ConstEnumOnly */;
+                        return false;
+                    case 1 /* Instantiated */:
+                        // child is instantiated - record state and stop
+                        state_1 = 1 /* Instantiated */;
+                        return true;
+                }
+            });
+            return state_1;
+        }
+        else if (node.kind === 233 /* ModuleDeclaration */) {
+            var body = node.body;
+            return body ? getModuleInstanceState(body) : 1 /* Instantiated */;
+        }
+        else if (node.kind === 71 /* Identifier */ && node.isInJSDocNamespace) {
+            return 0 /* NonInstantiated */;
+        }
+        else {
+            return 1 /* Instantiated */;
+        }
+    }
+    ts.getModuleInstanceState = getModuleInstanceState;
+    var ContainerFlags;
+    (function (ContainerFlags) {
+        // The current node is not a container, and no container manipulation should happen before
+        // recursing into it.
+        ContainerFlags[ContainerFlags["None"] = 0] = "None";
+        // The current node is a container.  It should be set as the current container (and block-
+        // container) before recursing into it.  The current node does not have locals.  Examples:
+        //
+        //      Classes, ObjectLiterals, TypeLiterals, Interfaces...
+        ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
+        // The current node is a block-scoped-container.  It should be set as the current block-
+        // container before recursing into it.  Examples:
+        //
+        //      Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
+        ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
+        // The current node is the container of a control flow path. The current control flow should
+        // be saved and restored, and a new control flow initialized within the container.
+        ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer";
+        ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike";
+        ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression";
+        ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals";
+        ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface";
+        ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod";
+    })(ContainerFlags || (ContainerFlags = {}));
+    var binder = createBinder();
+    function bindSourceFile(file, options) {
+        ts.performance.mark("beforeBind");
+        binder(file, options);
+        ts.performance.mark("afterBind");
+        ts.performance.measure("Bind", "beforeBind", "afterBind");
+    }
+    ts.bindSourceFile = bindSourceFile;
+    function createBinder() {
+        var file;
+        var options;
+        var languageVersion;
+        var parent;
+        var container;
+        var blockScopeContainer;
+        var lastContainer;
+        var seenThisKeyword;
+        // state used by control flow analysis
+        var currentFlow;
+        var currentBreakTarget;
+        var currentContinueTarget;
+        var currentReturnTarget;
+        var currentTrueTarget;
+        var currentFalseTarget;
+        var preSwitchCaseFlow;
+        var activeLabels;
+        var hasExplicitReturn;
+        // state used for emit helpers
+        var emitFlags;
+        // If this file is an external module, then it is automatically in strict-mode according to
+        // ES6.  If it is not an external module, then we'll determine if it is in strict mode or
+        // not depending on if we see "use strict" in certain places or if we hit a class/namespace
+        // or if compiler options contain alwaysStrict.
+        var inStrictMode;
+        var symbolCount = 0;
+        var Symbol;
+        var classifiableNames;
+        var unreachableFlow = { flags: 1 /* Unreachable */ };
+        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
+        // state used to aggregate transform flags during bind.
+        var subtreeTransformFlags = 0 /* None */;
+        var skipTransformFlagAggregation;
+        /**
+         * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
+         * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
+         * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
+         */
+        function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
+            return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
+        }
+        function bindSourceFile(f, opts) {
+            file = f;
+            options = opts;
+            languageVersion = ts.getEmitScriptTarget(options);
+            inStrictMode = bindInStrictMode(file, opts);
+            classifiableNames = ts.createUnderscoreEscapedMap();
+            symbolCount = 0;
+            skipTransformFlagAggregation = file.isDeclarationFile;
+            Symbol = ts.objectAllocator.getSymbolConstructor();
+            if (!file.locals) {
+                bind(file);
+                file.symbolCount = symbolCount;
+                file.classifiableNames = classifiableNames;
+            }
+            file = undefined;
+            options = undefined;
+            languageVersion = undefined;
+            parent = undefined;
+            container = undefined;
+            blockScopeContainer = undefined;
+            lastContainer = undefined;
+            seenThisKeyword = false;
+            currentFlow = undefined;
+            currentBreakTarget = undefined;
+            currentContinueTarget = undefined;
+            currentReturnTarget = undefined;
+            currentTrueTarget = undefined;
+            currentFalseTarget = undefined;
+            activeLabels = undefined;
+            hasExplicitReturn = false;
+            emitFlags = 0 /* None */;
+            subtreeTransformFlags = 0 /* None */;
+        }
+        return bindSourceFile;
+        function bindInStrictMode(file, opts) {
+            if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !file.isDeclarationFile) {
+                // bind in strict mode source files with alwaysStrict option
+                return true;
+            }
+            else {
+                return !!file.externalModuleIndicator;
+            }
+        }
+        function createSymbol(flags, name) {
+            symbolCount++;
+            return new Symbol(flags, name);
+        }
+        function addDeclarationToSymbol(symbol, node, symbolFlags) {
+            symbol.flags |= symbolFlags;
+            node.symbol = symbol;
+            if (!symbol.declarations) {
+                symbol.declarations = [node];
+            }
+            else {
+                symbol.declarations.push(node);
+            }
+            if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
+                symbol.exports = ts.createSymbolTable();
+            }
+            if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
+                symbol.members = ts.createSymbolTable();
+            }
+            if (symbolFlags & 107455 /* Value */) {
+                var valueDeclaration = symbol.valueDeclaration;
+                if (!valueDeclaration ||
+                    (valueDeclaration.kind !== node.kind && valueDeclaration.kind === 233 /* ModuleDeclaration */)) {
+                    // other kinds of value declarations take precedence over modules
+                    symbol.valueDeclaration = node;
+                }
+            }
+        }
+        // Should not be called on a declaration with a computed property name,
+        // unless it is a well known Symbol.
+        function getDeclarationName(node) {
+            if (node.kind === 243 /* ExportAssignment */) {
+                return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
+            }
+            var name = ts.getNameOfDeclaration(node);
+            if (name) {
+                if (ts.isAmbientModule(node)) {
+                    var moduleName = ts.getTextOfIdentifierOrLiteral(name);
+                    return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\"");
+                }
+                if (name.kind === 144 /* ComputedPropertyName */) {
+                    var nameExpression = name.expression;
+                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
+                    if (ts.isStringOrNumericLiteral(nameExpression)) {
+                        return ts.escapeLeadingUnderscores(nameExpression.text);
+                    }
+                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
+                    return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
+                }
+                return ts.getEscapedTextOfIdentifierOrLiteral(name);
+            }
+            switch (node.kind) {
+                case 152 /* Constructor */:
+                    return "__constructor" /* Constructor */;
+                case 160 /* FunctionType */:
+                case 155 /* CallSignature */:
+                    return "__call" /* Call */;
+                case 161 /* ConstructorType */:
+                case 156 /* ConstructSignature */:
+                    return "__new" /* New */;
+                case 157 /* IndexSignature */:
+                    return "__index" /* Index */;
+                case 244 /* ExportDeclaration */:
+                    return "__export" /* ExportStar */;
+                case 194 /* BinaryExpression */:
+                    if (ts.getSpecialPropertyAssignmentKind(node) === 2 /* ModuleExports */) {
+                        // module.exports = ...
+                        return "export=" /* ExportEquals */;
+                    }
+                    ts.Debug.fail("Unknown binary declaration kind");
+                    break;
+                case 228 /* FunctionDeclaration */:
+                case 229 /* ClassDeclaration */:
+                    return (ts.hasModifier(node, 512 /* Default */) ? "default" /* Default */ : undefined);
+                case 273 /* JSDocFunctionType */:
+                    return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */);
+                case 146 /* Parameter */:
+                    // Parameters with names are handled at the top of this function.  Parameters
+                    // without names can only come from JSDocFunctionTypes.
+                    ts.Debug.assert(node.parent.kind === 273 /* JSDocFunctionType */);
+                    var functionType = node.parent;
+                    var index = ts.indexOf(functionType.parameters, node);
+                    return "arg" + index;
+                case 283 /* JSDocTypedefTag */:
+                    var name_2 = ts.getNameOfJSDocTypedef(node);
+                    return typeof name_2 !== "undefined" ? name_2.escapedText : undefined;
+            }
+        }
+        function getDisplayName(node) {
+            return node.name ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(getDeclarationName(node));
+        }
+        /**
+         * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
+         * @param symbolTable - The symbol table which node will be added to.
+         * @param parent - node's parent declaration.
+         * @param node - The declaration to be added to the symbol table
+         * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
+         * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
+         */
+        function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) {
+            ts.Debug.assert(!ts.hasDynamicName(node));
+            var isDefaultExport = ts.hasModifier(node, 512 /* Default */);
+            // The exported symbol for an export default function/class node is always named "default"
+            var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node);
+            var symbol;
+            if (name === undefined) {
+                symbol = createSymbol(0 /* None */, "__missing" /* Missing */);
+            }
+            else {
+                // Check and see if the symbol table already has a symbol with this name.  If not,
+                // create a new symbol with this name and add it to the table.  Note that we don't
+                // give the new symbol any flags *yet*.  This ensures that it will not conflict
+                // with the 'excludes' flags we pass in.
+                //
+                // If we do get an existing symbol, see if it conflicts with the new symbol we're
+                // creating.  For example, a 'var' symbol and a 'class' symbol will conflict within
+                // the same symbol table.  If we have a conflict, report the issue on each
+                // declaration we have for this symbol, and then create a new symbol for this
+                // declaration.
+                //
+                // Note that when properties declared in Javascript constructors
+                // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
+                // Always. This allows the common Javascript pattern of overwriting a prototype method
+                // with an bound instance method of the same type: `this.method = this.method.bind(this)`
+                //
+                // If we created a new symbol, either because we didn't have a symbol with this name
+                // in the symbol table, or we conflicted with an existing symbol, then just add this
+                // node as the sole declaration of the new symbol.
+                //
+                // Otherwise, we'll be merging into a compatible existing symbol (for example when
+                // you have multiple 'vars' with the same name in the same container).  In this case
+                // just add this node into the declarations list of the symbol.
+                symbol = symbolTable.get(name);
+                if (includes & 788448 /* Classifiable */) {
+                    classifiableNames.set(name, true);
+                }
+                if (!symbol) {
+                    symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
+                    if (isReplaceableByMethod)
+                        symbol.isReplaceableByMethod = true;
+                }
+                else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
+                    // A symbol already exists, so don't add this as a declaration.
+                    return symbol;
+                }
+                else if (symbol.flags & excludes) {
+                    if (symbol.isReplaceableByMethod) {
+                        // Javascript constructor-declared symbols can be discarded in favor of
+                        // prototype symbols like methods.
+                        symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
+                    }
+                    else {
+                        if (node.name) {
+                            node.name.parent = node;
+                        }
+                        // Report errors every position with duplicate declaration
+                        // Report errors on previous encountered declarations
+                        var message_1 = symbol.flags & 2 /* BlockScopedVariable */
+                            ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
+                            : ts.Diagnostics.Duplicate_identifier_0;
+                        if (symbol.declarations && symbol.declarations.length) {
+                            // If the current node is a default export of some sort, then check if
+                            // there are any other default exports that we need to error on.
+                            // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
+                            if (isDefaultExport) {
+                                message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
+                            }
+                            else {
+                                // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
+                                // Error on multiple export default in the following case:
+                                // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
+                                // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
+                                if (symbol.declarations && symbol.declarations.length &&
+                                    (isDefaultExport || (node.kind === 243 /* ExportAssignment */ && !node.isExportEquals))) {
+                                    message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
+                                }
+                            }
+                        }
+                        ts.forEach(symbol.declarations, function (declaration) {
+                            file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(declaration) || declaration, message_1, getDisplayName(declaration)));
+                        });
+                        file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(node) || node, message_1, getDisplayName(node)));
+                        symbol = createSymbol(0 /* None */, name);
+                    }
+                }
+            }
+            addDeclarationToSymbol(symbol, node, includes);
+            symbol.parent = parent;
+            return symbol;
+        }
+        function declareModuleMember(node, symbolFlags, symbolExcludes) {
+            var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */;
+            if (symbolFlags & 2097152 /* Alias */) {
+                if (node.kind === 246 /* ExportSpecifier */ || (node.kind === 237 /* ImportEqualsDeclaration */ && hasExportModifier)) {
+                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+                }
+                else {
+                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
+                }
+            }
+            else {
+                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
+                // and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
+                //
+                //   1. We treat locals and exports of the same name as mutually exclusive within a container.
+                //      That means the binder will issue a Duplicate Identifier error if you mix locals and exports
+                //      with the same name in the same container.
+                //      TODO: Make this a more specific error and decouple it from the exclusion logic.
+                //   2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
+                //      but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
+                //      when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
+                // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
+                //       during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
+                //       and this case is specially handled. Module augmentations should only be merged with original module definition
+                //       and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
+                if (node.kind === 283 /* JSDocTypedefTag */)
+                    ts.Debug.assert(ts.isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
+                var isJSDocTypedefInJSDocNamespace = node.kind === 283 /* JSDocTypedefTag */ &&
+                    node.name &&
+                    node.name.kind === 71 /* Identifier */ &&
+                    node.name.isInJSDocNamespace;
+                if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 32 /* ExportContext */)) || isJSDocTypedefInJSDocNamespace) {
+                    var exportKind = symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0;
+                    var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
+                    local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+                    node.localSymbol = local;
+                    return local;
+                }
+                else {
+                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
+                }
+            }
+        }
+        // All container nodes are kept on a linked list in declaration order. This list is used by
+        // the getLocalNameOfContainer function in the type checker to validate that the local name
+        // used for a container is unique.
+        function bindContainer(node, containerFlags) {
+            // Before we recurse into a node's children, we first save the existing parent, container
+            // and block-container.  Then after we pop out of processing the children, we restore
+            // these saved values.
+            var saveContainer = container;
+            var savedBlockScopeContainer = blockScopeContainer;
+            // Depending on what kind of node this is, we may have to adjust the current container
+            // and block-container.   If the current node is a container, then it is automatically
+            // considered the current block-container as well.  Also, for containers that we know
+            // may contain locals, we proactively initialize the .locals field. We do this because
+            // it's highly likely that the .locals will be needed to place some child in (for example,
+            // a parameter, or variable declaration).
+            //
+            // However, we do not proactively create the .locals for block-containers because it's
+            // totally normal and common for block-containers to never actually have a block-scoped
+            // variable in them.  We don't want to end up allocating an object for every 'block' we
+            // run into when most of them won't be necessary.
+            //
+            // Finally, if this is a block-container, then we clear out any existing .locals object
+            // it may contain within it.  This happens in incremental scenarios.  Because we can be
+            // reusing a node from a previous compilation, that node may have had 'locals' created
+            // for it.  We must clear this so we don't accidentally move any stale data forward from
+            // a previous compilation.
+            if (containerFlags & 1 /* IsContainer */) {
+                container = blockScopeContainer = node;
+                if (containerFlags & 32 /* HasLocals */) {
+                    container.locals = ts.createSymbolTable();
+                }
+                addToContainerChain(container);
+            }
+            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
+                blockScopeContainer = node;
+                blockScopeContainer.locals = undefined;
+            }
+            if (containerFlags & 4 /* IsControlFlowContainer */) {
+                var saveCurrentFlow = currentFlow;
+                var saveBreakTarget = currentBreakTarget;
+                var saveContinueTarget = currentContinueTarget;
+                var saveReturnTarget = currentReturnTarget;
+                var saveActiveLabels = activeLabels;
+                var saveHasExplicitReturn = hasExplicitReturn;
+                var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) && !!ts.getImmediatelyInvokedFunctionExpression(node);
+                // A non-async IIFE is considered part of the containing control flow. Return statements behave
+                // similarly to break statements that exit to a label just past the statement body.
+                if (isIIFE) {
+                    currentReturnTarget = createBranchLabel();
+                }
+                else {
+                    currentFlow = { flags: 2 /* Start */ };
+                    if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) {
+                        currentFlow.container = node;
+                    }
+                    currentReturnTarget = undefined;
+                }
+                currentBreakTarget = undefined;
+                currentContinueTarget = undefined;
+                activeLabels = undefined;
+                hasExplicitReturn = false;
+                bindChildren(node);
+                // Reset all reachability check related flags on node (for incremental scenarios)
+                node.flags &= ~1408 /* ReachabilityAndEmitFlags */;
+                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
+                    node.flags |= 128 /* HasImplicitReturn */;
+                    if (hasExplicitReturn)
+                        node.flags |= 256 /* HasExplicitReturn */;
+                }
+                if (node.kind === 265 /* SourceFile */) {
+                    node.flags |= emitFlags;
+                }
+                if (isIIFE) {
+                    addAntecedent(currentReturnTarget, currentFlow);
+                    currentFlow = finishFlowLabel(currentReturnTarget);
+                }
+                else {
+                    currentFlow = saveCurrentFlow;
+                }
+                currentBreakTarget = saveBreakTarget;
+                currentContinueTarget = saveContinueTarget;
+                currentReturnTarget = saveReturnTarget;
+                activeLabels = saveActiveLabels;
+                hasExplicitReturn = saveHasExplicitReturn;
+            }
+            else if (containerFlags & 64 /* IsInterface */) {
+                seenThisKeyword = false;
+                bindChildren(node);
+                node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */;
+            }
+            else {
+                bindChildren(node);
+            }
+            container = saveContainer;
+            blockScopeContainer = savedBlockScopeContainer;
+        }
+        function bindChildren(node) {
+            if (skipTransformFlagAggregation) {
+                bindChildrenWorker(node);
+            }
+            else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
+                skipTransformFlagAggregation = true;
+                bindChildrenWorker(node);
+                skipTransformFlagAggregation = false;
+                subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
+            }
+            else {
+                var savedSubtreeTransformFlags = subtreeTransformFlags;
+                subtreeTransformFlags = 0;
+                bindChildrenWorker(node);
+                subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
+            }
+        }
+        function bindEach(nodes) {
+            if (nodes === undefined) {
+                return;
+            }
+            if (skipTransformFlagAggregation) {
+                ts.forEach(nodes, bind);
+            }
+            else {
+                var savedSubtreeTransformFlags = subtreeTransformFlags;
+                subtreeTransformFlags = 0 /* None */;
+                var nodeArrayFlags = 0 /* None */;
+                for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
+                    var node = nodes_2[_i];
+                    bind(node);
+                    nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
+                }
+                nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
+                subtreeTransformFlags |= savedSubtreeTransformFlags;
+            }
+        }
+        function bindEachChild(node) {
+            ts.forEachChild(node, bind, bindEach);
+        }
+        function bindChildrenWorker(node) {
+            // Binding of JsDocComment should be done before the current block scope container changes.
+            // because the scope of JsDocComment should not be affected by whether the current node is a
+            // container or not.
+            if (ts.hasJSDocNodes(node)) {
+                if (ts.isInJavaScriptFile(node)) {
+                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
+                        var j = _a[_i];
+                        bind(j);
+                    }
+                }
+                else {
+                    for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) {
+                        var j = _c[_b];
+                        setParentPointers(node, j);
+                    }
+                }
+            }
+            if (checkUnreachable(node)) {
+                bindEachChild(node);
+                return;
+            }
+            switch (node.kind) {
+                case 213 /* WhileStatement */:
+                    bindWhileStatement(node);
+                    break;
+                case 212 /* DoStatement */:
+                    bindDoStatement(node);
+                    break;
+                case 214 /* ForStatement */:
+                    bindForStatement(node);
+                    break;
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                    bindForInOrForOfStatement(node);
+                    break;
+                case 211 /* IfStatement */:
+                    bindIfStatement(node);
+                    break;
+                case 219 /* ReturnStatement */:
+                case 223 /* ThrowStatement */:
+                    bindReturnOrThrow(node);
+                    break;
+                case 218 /* BreakStatement */:
+                case 217 /* ContinueStatement */:
+                    bindBreakOrContinueStatement(node);
+                    break;
+                case 224 /* TryStatement */:
+                    bindTryStatement(node);
+                    break;
+                case 221 /* SwitchStatement */:
+                    bindSwitchStatement(node);
+                    break;
+                case 235 /* CaseBlock */:
+                    bindCaseBlock(node);
+                    break;
+                case 257 /* CaseClause */:
+                    bindCaseClause(node);
+                    break;
+                case 222 /* LabeledStatement */:
+                    bindLabeledStatement(node);
+                    break;
+                case 192 /* PrefixUnaryExpression */:
+                    bindPrefixUnaryExpressionFlow(node);
+                    break;
+                case 193 /* PostfixUnaryExpression */:
+                    bindPostfixUnaryExpressionFlow(node);
+                    break;
+                case 194 /* BinaryExpression */:
+                    bindBinaryExpressionFlow(node);
+                    break;
+                case 188 /* DeleteExpression */:
+                    bindDeleteExpressionFlow(node);
+                    break;
+                case 195 /* ConditionalExpression */:
+                    bindConditionalExpressionFlow(node);
+                    break;
+                case 226 /* VariableDeclaration */:
+                    bindVariableDeclarationFlow(node);
+                    break;
+                case 181 /* CallExpression */:
+                    bindCallExpressionFlow(node);
+                    break;
+                case 275 /* JSDocComment */:
+                    bindJSDocComment(node);
+                    break;
+                case 283 /* JSDocTypedefTag */:
+                    bindJSDocTypedefTag(node);
+                    break;
+                default:
+                    bindEachChild(node);
+                    break;
+            }
+        }
+        function isNarrowingExpression(expr) {
+            switch (expr.kind) {
+                case 71 /* Identifier */:
+                case 99 /* ThisKeyword */:
+                case 179 /* PropertyAccessExpression */:
+                    return isNarrowableReference(expr);
+                case 181 /* CallExpression */:
+                    return hasNarrowableArgument(expr);
+                case 185 /* ParenthesizedExpression */:
+                    return isNarrowingExpression(expr.expression);
+                case 194 /* BinaryExpression */:
+                    return isNarrowingBinaryExpression(expr);
+                case 192 /* PrefixUnaryExpression */:
+                    return expr.operator === 51 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
+            }
+            return false;
+        }
+        function isNarrowableReference(expr) {
+            return expr.kind === 71 /* Identifier */ ||
+                expr.kind === 99 /* ThisKeyword */ ||
+                expr.kind === 97 /* SuperKeyword */ ||
+                expr.kind === 179 /* PropertyAccessExpression */ && isNarrowableReference(expr.expression);
+        }
+        function hasNarrowableArgument(expr) {
+            if (expr.arguments) {
+                for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) {
+                    var argument = _a[_i];
+                    if (isNarrowableReference(argument)) {
+                        return true;
+                    }
+                }
+            }
+            if (expr.expression.kind === 179 /* PropertyAccessExpression */ &&
+                isNarrowableReference(expr.expression.expression)) {
+                return true;
+            }
+            return false;
+        }
+        function isNarrowingTypeofOperands(expr1, expr2) {
+            return expr1.kind === 189 /* TypeOfExpression */ && isNarrowableOperand(expr1.expression) && expr2.kind === 9 /* StringLiteral */;
+        }
+        function isNarrowingBinaryExpression(expr) {
+            switch (expr.operatorToken.kind) {
+                case 58 /* EqualsToken */:
+                    return isNarrowableReference(expr.left);
+                case 32 /* EqualsEqualsToken */:
+                case 33 /* ExclamationEqualsToken */:
+                case 34 /* EqualsEqualsEqualsToken */:
+                case 35 /* ExclamationEqualsEqualsToken */:
+                    return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
+                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
+                case 93 /* InstanceOfKeyword */:
+                    return isNarrowableOperand(expr.left);
+                case 26 /* CommaToken */:
+                    return isNarrowingExpression(expr.right);
+            }
+            return false;
+        }
+        function isNarrowableOperand(expr) {
+            switch (expr.kind) {
+                case 185 /* ParenthesizedExpression */:
+                    return isNarrowableOperand(expr.expression);
+                case 194 /* BinaryExpression */:
+                    switch (expr.operatorToken.kind) {
+                        case 58 /* EqualsToken */:
+                            return isNarrowableOperand(expr.left);
+                        case 26 /* CommaToken */:
+                            return isNarrowableOperand(expr.right);
+                    }
+            }
+            return isNarrowableReference(expr);
+        }
+        function createBranchLabel() {
+            return {
+                flags: 4 /* BranchLabel */,
+                antecedents: undefined
+            };
+        }
+        function createLoopLabel() {
+            return {
+                flags: 8 /* LoopLabel */,
+                antecedents: undefined
+            };
+        }
+        function setFlowNodeReferenced(flow) {
+            // On first reference we set the Referenced flag, thereafter we set the Shared flag
+            flow.flags |= flow.flags & 512 /* Referenced */ ? 1024 /* Shared */ : 512 /* Referenced */;
+        }
+        function addAntecedent(label, antecedent) {
+            if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) {
+                (label.antecedents || (label.antecedents = [])).push(antecedent);
+                setFlowNodeReferenced(antecedent);
+            }
+        }
+        function createFlowCondition(flags, antecedent, expression) {
+            if (antecedent.flags & 1 /* Unreachable */) {
+                return antecedent;
+            }
+            if (!expression) {
+                return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow;
+            }
+            if (expression.kind === 101 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
+                expression.kind === 86 /* FalseKeyword */ && flags & 32 /* TrueCondition */) {
+                return unreachableFlow;
+            }
+            if (!isNarrowingExpression(expression)) {
+                return antecedent;
+            }
+            setFlowNodeReferenced(antecedent);
+            return { flags: flags, expression: expression, antecedent: antecedent };
+        }
+        function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) {
+            if (!isNarrowingExpression(switchStatement.expression)) {
+                return antecedent;
+            }
+            setFlowNodeReferenced(antecedent);
+            return { flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent };
+        }
+        function createFlowAssignment(antecedent, node) {
+            setFlowNodeReferenced(antecedent);
+            return { flags: 16 /* Assignment */, antecedent: antecedent, node: node };
+        }
+        function createFlowArrayMutation(antecedent, node) {
+            setFlowNodeReferenced(antecedent);
+            var res = { flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node };
+            return res;
+        }
+        function finishFlowLabel(flow) {
+            var antecedents = flow.antecedents;
+            if (!antecedents) {
+                return unreachableFlow;
+            }
+            if (antecedents.length === 1) {
+                return antecedents[0];
+            }
+            return flow;
+        }
+        function isStatementCondition(node) {
+            var parent = node.parent;
+            switch (parent.kind) {
+                case 211 /* IfStatement */:
+                case 213 /* WhileStatement */:
+                case 212 /* DoStatement */:
+                    return parent.expression === node;
+                case 214 /* ForStatement */:
+                case 195 /* ConditionalExpression */:
+                    return parent.condition === node;
+            }
+            return false;
+        }
+        function isLogicalExpression(node) {
+            while (true) {
+                if (node.kind === 185 /* ParenthesizedExpression */) {
+                    node = node.expression;
+                }
+                else if (node.kind === 192 /* PrefixUnaryExpression */ && node.operator === 51 /* ExclamationToken */) {
+                    node = node.operand;
+                }
+                else {
+                    return node.kind === 194 /* BinaryExpression */ && (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */ ||
+                        node.operatorToken.kind === 54 /* BarBarToken */);
+                }
+            }
+        }
+        function isTopLevelLogicalExpression(node) {
+            while (node.parent.kind === 185 /* ParenthesizedExpression */ ||
+                node.parent.kind === 192 /* PrefixUnaryExpression */ &&
+                    node.parent.operator === 51 /* ExclamationToken */) {
+                node = node.parent;
+            }
+            return !isStatementCondition(node) && !isLogicalExpression(node.parent);
+        }
+        function bindCondition(node, trueTarget, falseTarget) {
+            var saveTrueTarget = currentTrueTarget;
+            var saveFalseTarget = currentFalseTarget;
+            currentTrueTarget = trueTarget;
+            currentFalseTarget = falseTarget;
+            bind(node);
+            currentTrueTarget = saveTrueTarget;
+            currentFalseTarget = saveFalseTarget;
+            if (!node || !isLogicalExpression(node)) {
+                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
+                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
+            }
+        }
+        function bindIterativeStatement(node, breakTarget, continueTarget) {
+            var saveBreakTarget = currentBreakTarget;
+            var saveContinueTarget = currentContinueTarget;
+            currentBreakTarget = breakTarget;
+            currentContinueTarget = continueTarget;
+            bind(node);
+            currentBreakTarget = saveBreakTarget;
+            currentContinueTarget = saveContinueTarget;
+        }
+        function bindWhileStatement(node) {
+            var preWhileLabel = createLoopLabel();
+            var preBodyLabel = createBranchLabel();
+            var postWhileLabel = createBranchLabel();
+            addAntecedent(preWhileLabel, currentFlow);
+            currentFlow = preWhileLabel;
+            bindCondition(node.expression, preBodyLabel, postWhileLabel);
+            currentFlow = finishFlowLabel(preBodyLabel);
+            bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
+            addAntecedent(preWhileLabel, currentFlow);
+            currentFlow = finishFlowLabel(postWhileLabel);
+        }
+        function bindDoStatement(node) {
+            var preDoLabel = createLoopLabel();
+            var enclosingLabeledStatement = node.parent.kind === 222 /* LabeledStatement */
+                ? ts.lastOrUndefined(activeLabels)
+                : undefined;
+            // if do statement is wrapped in labeled statement then target labels for break/continue with or without
+            // label should be the same
+            var preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
+            var postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
+            addAntecedent(preDoLabel, currentFlow);
+            currentFlow = preDoLabel;
+            bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
+            addAntecedent(preConditionLabel, currentFlow);
+            currentFlow = finishFlowLabel(preConditionLabel);
+            bindCondition(node.expression, preDoLabel, postDoLabel);
+            currentFlow = finishFlowLabel(postDoLabel);
+        }
+        function bindForStatement(node) {
+            var preLoopLabel = createLoopLabel();
+            var preBodyLabel = createBranchLabel();
+            var postLoopLabel = createBranchLabel();
+            bind(node.initializer);
+            addAntecedent(preLoopLabel, currentFlow);
+            currentFlow = preLoopLabel;
+            bindCondition(node.condition, preBodyLabel, postLoopLabel);
+            currentFlow = finishFlowLabel(preBodyLabel);
+            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
+            bind(node.incrementor);
+            addAntecedent(preLoopLabel, currentFlow);
+            currentFlow = finishFlowLabel(postLoopLabel);
+        }
+        function bindForInOrForOfStatement(node) {
+            var preLoopLabel = createLoopLabel();
+            var postLoopLabel = createBranchLabel();
+            addAntecedent(preLoopLabel, currentFlow);
+            currentFlow = preLoopLabel;
+            if (node.kind === 216 /* ForOfStatement */) {
+                bind(node.awaitModifier);
+            }
+            bind(node.expression);
+            addAntecedent(postLoopLabel, currentFlow);
+            bind(node.initializer);
+            if (node.initializer.kind !== 227 /* VariableDeclarationList */) {
+                bindAssignmentTargetFlow(node.initializer);
+            }
+            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
+            addAntecedent(preLoopLabel, currentFlow);
+            currentFlow = finishFlowLabel(postLoopLabel);
+        }
+        function bindIfStatement(node) {
+            var thenLabel = createBranchLabel();
+            var elseLabel = createBranchLabel();
+            var postIfLabel = createBranchLabel();
+            bindCondition(node.expression, thenLabel, elseLabel);
+            currentFlow = finishFlowLabel(thenLabel);
+            bind(node.thenStatement);
+            addAntecedent(postIfLabel, currentFlow);
+            currentFlow = finishFlowLabel(elseLabel);
+            bind(node.elseStatement);
+            addAntecedent(postIfLabel, currentFlow);
+            currentFlow = finishFlowLabel(postIfLabel);
+        }
+        function bindReturnOrThrow(node) {
+            bind(node.expression);
+            if (node.kind === 219 /* ReturnStatement */) {
+                hasExplicitReturn = true;
+                if (currentReturnTarget) {
+                    addAntecedent(currentReturnTarget, currentFlow);
+                }
+            }
+            currentFlow = unreachableFlow;
+        }
+        function findActiveLabel(name) {
+            if (activeLabels) {
+                for (var _i = 0, activeLabels_1 = activeLabels; _i < activeLabels_1.length; _i++) {
+                    var label = activeLabels_1[_i];
+                    if (label.name === name) {
+                        return label;
+                    }
+                }
+            }
+            return undefined;
+        }
+        function bindBreakOrContinueFlow(node, breakTarget, continueTarget) {
+            var flowLabel = node.kind === 218 /* BreakStatement */ ? breakTarget : continueTarget;
+            if (flowLabel) {
+                addAntecedent(flowLabel, currentFlow);
+                currentFlow = unreachableFlow;
+            }
+        }
+        function bindBreakOrContinueStatement(node) {
+            bind(node.label);
+            if (node.label) {
+                var activeLabel = findActiveLabel(node.label.escapedText);
+                if (activeLabel) {
+                    activeLabel.referenced = true;
+                    bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
+                }
+            }
+            else {
+                bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
+            }
+        }
+        function bindTryStatement(node) {
+            var preFinallyLabel = createBranchLabel();
+            var preTryFlow = currentFlow;
+            // TODO: Every statement in try block is potentially an exit point!
+            bind(node.tryBlock);
+            addAntecedent(preFinallyLabel, currentFlow);
+            var flowAfterTry = currentFlow;
+            var flowAfterCatch = unreachableFlow;
+            if (node.catchClause) {
+                currentFlow = preTryFlow;
+                bind(node.catchClause);
+                addAntecedent(preFinallyLabel, currentFlow);
+                flowAfterCatch = currentFlow;
+            }
+            if (node.finallyBlock) {
+                // in finally flow is combined from pre-try/flow from try/flow from catch
+                // pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
+                // also for finally blocks we inject two extra edges into the flow graph.
+                // first -> edge that connects pre-try flow with the label at the beginning of the finally block, it has lock associated with it
+                // second -> edge that represents post-finally flow.
+                // these edges are used in following scenario:
+                // let a; (1)
+                // try { a = someOperation(); (2)}
+                // finally { (3) console.log(a) } (4)
+                // (5) a
+                // flow graph for this case looks roughly like this (arrows show ):
+                // (1-pre-try-flow) <--.. <-- (2-post-try-flow)
+                //  ^                                ^
+                //  |*****(3-pre-finally-label) -----|
+                //                ^
+                //                |-- ... <-- (4-post-finally-label) <--- (5)
+                // In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
+                // since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
+                // then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
+                // Simply speaking code inside finally block is treated as reachable as pre-try-flow
+                // since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
+                // However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
+                // final flows of these blocks without taking pre-try flow into account.
+                //
+                // extra edges that we inject allows to control this behavior
+                // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
+                var preFinallyFlow = { flags: 2048 /* PreFinally */, antecedent: preTryFlow, lock: {} };
+                addAntecedent(preFinallyLabel, preFinallyFlow);
+                currentFlow = finishFlowLabel(preFinallyLabel);
+                bind(node.finallyBlock);
+                // if flow after finally is unreachable - keep it
+                // otherwise check if flows after try and after catch are unreachable
+                // if yes - convert current flow to unreachable
+                // i.e.
+                // try { return "1" } finally { console.log(1); }
+                // console.log(2); // this line should be unreachable even if flow falls out of finally block
+                if (!(currentFlow.flags & 1 /* Unreachable */)) {
+                    if ((flowAfterTry.flags & 1 /* Unreachable */) && (flowAfterCatch.flags & 1 /* Unreachable */)) {
+                        currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
+                            ? reportedUnreachableFlow
+                            : unreachableFlow;
+                    }
+                }
+                if (!(currentFlow.flags & 1 /* Unreachable */)) {
+                    var afterFinallyFlow = { flags: 4096 /* AfterFinally */, antecedent: currentFlow };
+                    preFinallyFlow.lock = afterFinallyFlow;
+                    currentFlow = afterFinallyFlow;
+                }
+            }
+            else {
+                currentFlow = finishFlowLabel(preFinallyLabel);
+            }
+        }
+        function bindSwitchStatement(node) {
+            var postSwitchLabel = createBranchLabel();
+            bind(node.expression);
+            var saveBreakTarget = currentBreakTarget;
+            var savePreSwitchCaseFlow = preSwitchCaseFlow;
+            currentBreakTarget = postSwitchLabel;
+            preSwitchCaseFlow = currentFlow;
+            bind(node.caseBlock);
+            addAntecedent(postSwitchLabel, currentFlow);
+            var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 258 /* DefaultClause */; });
+            // We mark a switch statement as possibly exhaustive if it has no default clause and if all
+            // case clauses have unreachable end points (e.g. they all return).
+            node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
+            if (!hasDefault) {
+                addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
+            }
+            currentBreakTarget = saveBreakTarget;
+            preSwitchCaseFlow = savePreSwitchCaseFlow;
+            currentFlow = finishFlowLabel(postSwitchLabel);
+        }
+        function bindCaseBlock(node) {
+            var savedSubtreeTransformFlags = subtreeTransformFlags;
+            subtreeTransformFlags = 0;
+            var clauses = node.clauses;
+            var fallthroughFlow = unreachableFlow;
+            for (var i = 0; i < clauses.length; i++) {
+                var clauseStart = i;
+                while (!clauses[i].statements.length && i + 1 < clauses.length) {
+                    bind(clauses[i]);
+                    i++;
+                }
+                var preCaseLabel = createBranchLabel();
+                addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1));
+                addAntecedent(preCaseLabel, fallthroughFlow);
+                currentFlow = finishFlowLabel(preCaseLabel);
+                var clause = clauses[i];
+                bind(clause);
+                fallthroughFlow = currentFlow;
+                if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) {
+                    errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
+                }
+            }
+            clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */;
+            subtreeTransformFlags |= savedSubtreeTransformFlags;
+        }
+        function bindCaseClause(node) {
+            var saveCurrentFlow = currentFlow;
+            currentFlow = preSwitchCaseFlow;
+            bind(node.expression);
+            currentFlow = saveCurrentFlow;
+            bindEach(node.statements);
+        }
+        function pushActiveLabel(name, breakTarget, continueTarget) {
+            var activeLabel = {
+                name: name,
+                breakTarget: breakTarget,
+                continueTarget: continueTarget,
+                referenced: false
+            };
+            (activeLabels || (activeLabels = [])).push(activeLabel);
+            return activeLabel;
+        }
+        function popActiveLabel() {
+            activeLabels.pop();
+        }
+        function bindLabeledStatement(node) {
+            var preStatementLabel = createLoopLabel();
+            var postStatementLabel = createBranchLabel();
+            bind(node.label);
+            addAntecedent(preStatementLabel, currentFlow);
+            var activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel);
+            bind(node.statement);
+            popActiveLabel();
+            if (!activeLabel.referenced && !options.allowUnusedLabels) {
+                file.bindDiagnostics.push(createDiagnosticForNode(node.label, ts.Diagnostics.Unused_label));
+            }
+            if (!node.statement || node.statement.kind !== 212 /* DoStatement */) {
+                // do statement sets current flow inside bindDoStatement
+                addAntecedent(postStatementLabel, currentFlow);
+                currentFlow = finishFlowLabel(postStatementLabel);
+            }
+        }
+        function bindDestructuringTargetFlow(node) {
+            if (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */) {
+                bindAssignmentTargetFlow(node.left);
+            }
+            else {
+                bindAssignmentTargetFlow(node);
+            }
+        }
+        function bindAssignmentTargetFlow(node) {
+            if (isNarrowableReference(node)) {
+                currentFlow = createFlowAssignment(currentFlow, node);
+            }
+            else if (node.kind === 177 /* ArrayLiteralExpression */) {
+                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
+                    var e = _a[_i];
+                    if (e.kind === 198 /* SpreadElement */) {
+                        bindAssignmentTargetFlow(e.expression);
+                    }
+                    else {
+                        bindDestructuringTargetFlow(e);
+                    }
+                }
+            }
+            else if (node.kind === 178 /* ObjectLiteralExpression */) {
+                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
+                    var p = _c[_b];
+                    if (p.kind === 261 /* PropertyAssignment */) {
+                        bindDestructuringTargetFlow(p.initializer);
+                    }
+                    else if (p.kind === 262 /* ShorthandPropertyAssignment */) {
+                        bindAssignmentTargetFlow(p.name);
+                    }
+                    else if (p.kind === 263 /* SpreadAssignment */) {
+                        bindAssignmentTargetFlow(p.expression);
+                    }
+                }
+            }
+        }
+        function bindLogicalExpression(node, trueTarget, falseTarget) {
+            var preRightLabel = createBranchLabel();
+            if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) {
+                bindCondition(node.left, preRightLabel, falseTarget);
+            }
+            else {
+                bindCondition(node.left, trueTarget, preRightLabel);
+            }
+            currentFlow = finishFlowLabel(preRightLabel);
+            bind(node.operatorToken);
+            bindCondition(node.right, trueTarget, falseTarget);
+        }
+        function bindPrefixUnaryExpressionFlow(node) {
+            if (node.operator === 51 /* ExclamationToken */) {
+                var saveTrueTarget = currentTrueTarget;
+                currentTrueTarget = currentFalseTarget;
+                currentFalseTarget = saveTrueTarget;
+                bindEachChild(node);
+                currentFalseTarget = currentTrueTarget;
+                currentTrueTarget = saveTrueTarget;
+            }
+            else {
+                bindEachChild(node);
+                if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
+                    bindAssignmentTargetFlow(node.operand);
+                }
+            }
+        }
+        function bindPostfixUnaryExpressionFlow(node) {
+            bindEachChild(node);
+            if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
+                bindAssignmentTargetFlow(node.operand);
+            }
+        }
+        function bindBinaryExpressionFlow(node) {
+            var operator = node.operatorToken.kind;
+            if (operator === 53 /* AmpersandAmpersandToken */ || operator === 54 /* BarBarToken */) {
+                if (isTopLevelLogicalExpression(node)) {
+                    var postExpressionLabel = createBranchLabel();
+                    bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
+                    currentFlow = finishFlowLabel(postExpressionLabel);
+                }
+                else {
+                    bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
+                }
+            }
+            else {
+                bindEachChild(node);
+                if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) {
+                    bindAssignmentTargetFlow(node.left);
+                    if (operator === 58 /* EqualsToken */ && node.left.kind === 180 /* ElementAccessExpression */) {
+                        var elementAccess = node.left;
+                        if (isNarrowableOperand(elementAccess.expression)) {
+                            currentFlow = createFlowArrayMutation(currentFlow, node);
+                        }
+                    }
+                }
+            }
+        }
+        function bindDeleteExpressionFlow(node) {
+            bindEachChild(node);
+            if (node.expression.kind === 179 /* PropertyAccessExpression */) {
+                bindAssignmentTargetFlow(node.expression);
+            }
+        }
+        function bindConditionalExpressionFlow(node) {
+            var trueLabel = createBranchLabel();
+            var falseLabel = createBranchLabel();
+            var postExpressionLabel = createBranchLabel();
+            bindCondition(node.condition, trueLabel, falseLabel);
+            currentFlow = finishFlowLabel(trueLabel);
+            bind(node.questionToken);
+            bind(node.whenTrue);
+            addAntecedent(postExpressionLabel, currentFlow);
+            currentFlow = finishFlowLabel(falseLabel);
+            bind(node.colonToken);
+            bind(node.whenFalse);
+            addAntecedent(postExpressionLabel, currentFlow);
+            currentFlow = finishFlowLabel(postExpressionLabel);
+        }
+        function bindInitializedVariableFlow(node) {
+            var name = !ts.isOmittedExpression(node) ? node.name : undefined;
+            if (ts.isBindingPattern(name)) {
+                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    bindInitializedVariableFlow(child);
+                }
+            }
+            else {
+                currentFlow = createFlowAssignment(currentFlow, node);
+            }
+        }
+        function bindVariableDeclarationFlow(node) {
+            bindEachChild(node);
+            if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) {
+                bindInitializedVariableFlow(node);
+            }
+        }
+        function bindJSDocComment(node) {
+            ts.forEachChild(node, function (n) {
+                if (n.kind !== 283 /* JSDocTypedefTag */) {
+                    bind(n);
+                }
+            });
+        }
+        function bindJSDocTypedefTag(node) {
+            ts.forEachChild(node, function (n) {
+                // if the node has a fullName "A.B.C", that means symbol "C" was already bound
+                // when we visit "fullName"; so when we visit the name "C" as the next child of
+                // the jsDocTypedefTag, we should skip binding it.
+                if (node.fullName && n === node.name && node.fullName.kind !== 71 /* Identifier */) {
+                    return;
+                }
+                bind(n);
+            });
+        }
+        function bindCallExpressionFlow(node) {
+            // If the target of the call expression is a function expression or arrow function we have
+            // an immediately invoked function expression (IIFE). Initialize the flowNode property to
+            // the current control flow (which includes evaluation of the IIFE arguments).
+            var expr = node.expression;
+            while (expr.kind === 185 /* ParenthesizedExpression */) {
+                expr = expr.expression;
+            }
+            if (expr.kind === 186 /* FunctionExpression */ || expr.kind === 187 /* ArrowFunction */) {
+                bindEach(node.typeArguments);
+                bindEach(node.arguments);
+                bind(node.expression);
+            }
+            else {
+                bindEachChild(node);
+            }
+            if (node.expression.kind === 179 /* PropertyAccessExpression */) {
+                var propertyAccess = node.expression;
+                if (isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) {
+                    currentFlow = createFlowArrayMutation(currentFlow, node);
+                }
+            }
+        }
+        function getContainerFlags(node) {
+            switch (node.kind) {
+                case 199 /* ClassExpression */:
+                case 229 /* ClassDeclaration */:
+                case 232 /* EnumDeclaration */:
+                case 178 /* ObjectLiteralExpression */:
+                case 163 /* TypeLiteral */:
+                case 285 /* JSDocTypeLiteral */:
+                case 254 /* JsxAttributes */:
+                    return 1 /* IsContainer */;
+                case 230 /* InterfaceDeclaration */:
+                    return 1 /* IsContainer */ | 64 /* IsInterface */;
+                case 233 /* ModuleDeclaration */:
+                case 231 /* TypeAliasDeclaration */:
+                case 172 /* MappedType */:
+                    return 1 /* IsContainer */ | 32 /* HasLocals */;
+                case 265 /* SourceFile */:
+                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
+                case 151 /* MethodDeclaration */:
+                    if (ts.isObjectLiteralOrClassExpressionMethod(node)) {
+                        return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */;
+                    }
+                // falls through
+                case 152 /* Constructor */:
+                case 228 /* FunctionDeclaration */:
+                case 150 /* MethodSignature */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 155 /* CallSignature */:
+                case 273 /* JSDocFunctionType */:
+                case 160 /* FunctionType */:
+                case 156 /* ConstructSignature */:
+                case 157 /* IndexSignature */:
+                case 161 /* ConstructorType */:
+                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
+                case 234 /* ModuleBlock */:
+                    return 4 /* IsControlFlowContainer */;
+                case 149 /* PropertyDeclaration */:
+                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
+                case 260 /* CatchClause */:
+                case 214 /* ForStatement */:
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                case 235 /* CaseBlock */:
+                    return 2 /* IsBlockScopedContainer */;
+                case 207 /* Block */:
+                    // do not treat blocks directly inside a function as a block-scoped-container.
+                    // Locals that reside in this block should go to the function locals. Otherwise 'x'
+                    // would not appear to be a redeclaration of a block scoped local in the following
+                    // example:
+                    //
+                    //      function foo() {
+                    //          var x;
+                    //          let x;
+                    //      }
+                    //
+                    // If we placed 'var x' into the function locals and 'let x' into the locals of
+                    // the block, then there would be no collision.
+                    //
+                    // By not creating a new block-scoped-container here, we ensure that both 'var x'
+                    // and 'let x' go into the Function-container's locals, and we do get a collision
+                    // conflict.
+                    return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
+            }
+            return 0 /* None */;
+        }
+        function addToContainerChain(next) {
+            if (lastContainer) {
+                lastContainer.nextContainer = next;
+            }
+            lastContainer = next;
+        }
+        function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
+            switch (container.kind) {
+                // Modules, source files, and classes need specialized handling for how their
+                // members are declared (for example, a member of a class will go into a specific
+                // symbol table depending on if it is static or not). We defer to specialized
+                // handlers to take care of declaring these child members.
+                case 233 /* ModuleDeclaration */:
+                    return declareModuleMember(node, symbolFlags, symbolExcludes);
+                case 265 /* SourceFile */:
+                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
+                case 199 /* ClassExpression */:
+                case 229 /* ClassDeclaration */:
+                    return declareClassMember(node, symbolFlags, symbolExcludes);
+                case 232 /* EnumDeclaration */:
+                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+                case 163 /* TypeLiteral */:
+                case 285 /* JSDocTypeLiteral */:
+                case 178 /* ObjectLiteralExpression */:
+                case 230 /* InterfaceDeclaration */:
+                case 254 /* JsxAttributes */:
+                    // Interface/Object-types always have their children added to the 'members' of
+                    // their container. They are only accessible through an instance of their
+                    // container, and are never in scope otherwise (even inside the body of the
+                    // object / type / interface declaring them). An exception is type parameters,
+                    // which are in scope without qualification (similar to 'locals').
+                    return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+                case 160 /* FunctionType */:
+                case 161 /* ConstructorType */:
+                case 155 /* CallSignature */:
+                case 156 /* ConstructSignature */:
+                case 157 /* IndexSignature */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 152 /* Constructor */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                case 273 /* JSDocFunctionType */:
+                case 231 /* TypeAliasDeclaration */:
+                case 172 /* MappedType */:
+                    // All the children of these container types are never visible through another
+                    // symbol (i.e. through another symbol's 'exports' or 'members').  Instead,
+                    // they're only accessed 'lexically' (i.e. from code that exists underneath
+                    // their container in the tree). To accomplish this, we simply add their declared
+                    // symbol to the 'locals' of the container.  These symbols can then be found as
+                    // the type checker walks up the containers, checking them for matching names.
+                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
+            }
+        }
+        function declareClassMember(node, symbolFlags, symbolExcludes) {
+            return ts.hasModifier(node, 32 /* Static */)
+                ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
+                : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+        }
+        function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
+            return ts.isExternalModule(file)
+                ? declareModuleMember(node, symbolFlags, symbolExcludes)
+                : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
+        }
+        function hasExportDeclarations(node) {
+            var body = node.kind === 265 /* SourceFile */ ? node : node.body;
+            if (body && (body.kind === 265 /* SourceFile */ || body.kind === 234 /* ModuleBlock */)) {
+                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
+                    var stat = _a[_i];
+                    if (stat.kind === 244 /* ExportDeclaration */ || stat.kind === 243 /* ExportAssignment */) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        function setExportContextFlag(node) {
+            // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
+            // declarations with export modifiers) is an export context in which declarations are implicitly exported.
+            if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
+                node.flags |= 32 /* ExportContext */;
+            }
+            else {
+                node.flags &= ~32 /* ExportContext */;
+            }
+        }
+        function bindModuleDeclaration(node) {
+            setExportContextFlag(node);
+            if (ts.isAmbientModule(node)) {
+                if (ts.hasModifier(node, 1 /* Export */)) {
+                    errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
+                }
+                if (ts.isExternalModuleAugmentation(node)) {
+                    declareModuleSymbol(node);
+                }
+                else {
+                    var pattern = void 0;
+                    if (node.name.kind === 9 /* StringLiteral */) {
+                        var text = node.name.text;
+                        if (ts.hasZeroOrOneAsteriskCharacter(text)) {
+                            pattern = ts.tryParsePattern(text);
+                        }
+                        else {
+                            errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text);
+                        }
+                    }
+                    var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
+                    if (pattern) {
+                        (file.patternAmbientModules || (file.patternAmbientModules = [])).push({ pattern: pattern, symbol: symbol });
+                    }
+                }
+            }
+            else {
+                var state = declareModuleSymbol(node);
+                if (state !== 0 /* NonInstantiated */) {
+                    if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
+                        // if module was already merged with some function, class or non-const enum
+                        // treat is a non-const-enum-only
+                        node.symbol.constEnumOnlyModule = false;
+                    }
+                    else {
+                        var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
+                        if (node.symbol.constEnumOnlyModule === undefined) {
+                            // non-merged case - use the current state
+                            node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
+                        }
+                        else {
+                            // merged case: module is const enum only if all its pieces are non-instantiated or const enum
+                            node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
+                        }
+                    }
+                }
+            }
+        }
+        function declareModuleSymbol(node) {
+            var state = getModuleInstanceState(node);
+            var instantiated = state !== 0 /* NonInstantiated */;
+            declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 106639 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */);
+            return state;
+        }
+        function bindFunctionOrConstructorType(node) {
+            // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
+            // to the one we would get for: { <...>(...): T }
+            //
+            // We do that by making an anonymous type literal symbol, and then setting the function
+            // symbol as its sole member. To the rest of the system, this symbol will be  indistinguishable
+            // from an actual type literal symbol you would have gotten had you used the long form.
+            var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
+            addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
+            var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
+            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
+            typeLiteralSymbol.members = ts.createSymbolTable();
+            typeLiteralSymbol.members.set(symbol.escapedName, symbol);
+        }
+        function bindObjectLiteralExpression(node) {
+            var ElementKind;
+            (function (ElementKind) {
+                ElementKind[ElementKind["Property"] = 1] = "Property";
+                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
+            })(ElementKind || (ElementKind = {}));
+            if (inStrictMode) {
+                var seen = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    if (prop.kind === 263 /* SpreadAssignment */ || prop.name.kind !== 71 /* Identifier */) {
+                        continue;
+                    }
+                    var identifier = prop.name;
+                    // ECMA-262 11.1.5 Object Initializer
+                    // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
+                    // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
+                    // IsDataDescriptor(propId.descriptor) is true.
+                    //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
+                    //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
+                    //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
+                    // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
+                    var currentKind = prop.kind === 261 /* PropertyAssignment */ || prop.kind === 262 /* ShorthandPropertyAssignment */ || prop.kind === 151 /* MethodDeclaration */
+                        ? 1 /* Property */
+                        : 2 /* Accessor */;
+                    var existingKind = seen.get(identifier.escapedText);
+                    if (!existingKind) {
+                        seen.set(identifier.escapedText, currentKind);
+                        continue;
+                    }
+                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
+                        var span_1 = ts.getErrorSpanForNode(file, identifier);
+                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_1.start, span_1.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
+                    }
+                }
+            }
+            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */);
+        }
+        function bindJsxAttributes(node) {
+            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */);
+        }
+        function bindJsxAttribute(node, symbolFlags, symbolExcludes) {
+            return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
+        }
+        function bindAnonymousDeclaration(node, symbolFlags, name) {
+            var symbol = createSymbol(symbolFlags, name);
+            if (symbolFlags & 8 /* EnumMember */) {
+                symbol.parent = container.symbol;
+            }
+            addDeclarationToSymbol(symbol, node, symbolFlags);
+        }
+        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
+            switch (blockScopeContainer.kind) {
+                case 233 /* ModuleDeclaration */:
+                    declareModuleMember(node, symbolFlags, symbolExcludes);
+                    break;
+                case 265 /* SourceFile */:
+                    if (ts.isExternalModule(container)) {
+                        declareModuleMember(node, symbolFlags, symbolExcludes);
+                        break;
+                    }
+                // falls through
+                default:
+                    if (!blockScopeContainer.locals) {
+                        blockScopeContainer.locals = ts.createSymbolTable();
+                        addToContainerChain(blockScopeContainer);
+                    }
+                    declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
+            }
+        }
+        function bindBlockScopedVariableDeclaration(node) {
+            bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
+        }
+        // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
+        // check for reserved words used as identifiers in strict mode code.
+        function checkStrictModeIdentifier(node) {
+            if (inStrictMode &&
+                node.originalKeywordKind >= 108 /* FirstFutureReservedWord */ &&
+                node.originalKeywordKind <= 116 /* LastFutureReservedWord */ &&
+                !ts.isIdentifierName(node) &&
+                !ts.isInAmbientContext(node)) {
+                // Report error only if there are no parse errors in file
+                if (!file.parseDiagnostics.length) {
+                    file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
+                }
+            }
+        }
+        function getStrictModeIdentifierMessage(node) {
+            // Provide specialized messages to help the user understand why we think they're in
+            // strict mode.
+            if (ts.getContainingClass(node)) {
+                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
+            }
+            if (file.externalModuleIndicator) {
+                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
+            }
+            return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
+        }
+        function checkStrictModeBinaryExpression(node) {
+            if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
+                // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+                // Assignment operator(11.13) or of a PostfixExpression(11.3)
+                checkStrictModeEvalOrArguments(node, node.left);
+            }
+        }
+        function checkStrictModeCatchClause(node) {
+            // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
+            // Catch production is eval or arguments
+            if (inStrictMode && node.variableDeclaration) {
+                checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
+            }
+        }
+        function checkStrictModeDeleteExpression(node) {
+            // Grammar checking
+            if (inStrictMode && node.expression.kind === 71 /* Identifier */) {
+                // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
+                // UnaryExpression is a direct reference to a variable, function argument, or function name
+                var span_2 = ts.getErrorSpanForNode(file, node.expression);
+                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_2.start, span_2.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
+            }
+        }
+        function isEvalOrArgumentsIdentifier(node) {
+            return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
+        }
+        function checkStrictModeEvalOrArguments(contextNode, name) {
+            if (name && name.kind === 71 /* Identifier */) {
+                var identifier = name;
+                if (isEvalOrArgumentsIdentifier(identifier)) {
+                    // We check first if the name is inside class declaration or class expression; if so give explicit message
+                    // otherwise report generic error message.
+                    var span_3 = ts.getErrorSpanForNode(file, name);
+                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_3.start, span_3.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier)));
+                }
+            }
+        }
+        function getStrictModeEvalOrArgumentsMessage(node) {
+            // Provide specialized messages to help the user understand why we think they're in
+            // strict mode.
+            if (ts.getContainingClass(node)) {
+                return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
+            }
+            if (file.externalModuleIndicator) {
+                return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
+            }
+            return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
+        }
+        function checkStrictModeFunctionName(node) {
+            if (inStrictMode) {
+                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
+                checkStrictModeEvalOrArguments(node, node.name);
+            }
+        }
+        function getStrictModeBlockScopeFunctionDeclarationMessage(node) {
+            // Provide specialized messages to help the user understand why we think they're in
+            // strict mode.
+            if (ts.getContainingClass(node)) {
+                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode;
+            }
+            if (file.externalModuleIndicator) {
+                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode;
+            }
+            return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5;
+        }
+        function checkStrictModeFunctionDeclaration(node) {
+            if (languageVersion < 2 /* ES2015 */) {
+                // Report error if function is not top level function declaration
+                if (blockScopeContainer.kind !== 265 /* SourceFile */ &&
+                    blockScopeContainer.kind !== 233 /* ModuleDeclaration */ &&
+                    !ts.isFunctionLike(blockScopeContainer)) {
+                    // We check first if the name is inside class declaration or class expression; if so give explicit message
+                    // otherwise report generic error message.
+                    var errorSpan = ts.getErrorSpanForNode(file, node);
+                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node)));
+                }
+            }
+        }
+        function checkStrictModeNumericLiteral(node) {
+            if (inStrictMode && node.numericLiteralFlags & 4 /* Octal */) {
+                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
+            }
+        }
+        function checkStrictModePostfixUnaryExpression(node) {
+            // Grammar checking
+            // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+            // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
+            // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
+            if (inStrictMode) {
+                checkStrictModeEvalOrArguments(node, node.operand);
+            }
+        }
+        function checkStrictModePrefixUnaryExpression(node) {
+            // Grammar checking
+            if (inStrictMode) {
+                if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
+                    checkStrictModeEvalOrArguments(node, node.operand);
+                }
+            }
+        }
+        function checkStrictModeWithStatement(node) {
+            // Grammar checking for withStatement
+            if (inStrictMode) {
+                errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
+            }
+        }
+        function errorOnFirstToken(node, message, arg0, arg1, arg2) {
+            var span = ts.getSpanOfTokenAtPosition(file, node.pos);
+            file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
+        }
+        function bind(node) {
+            if (!node) {
+                return;
+            }
+            node.parent = parent;
+            var saveInStrictMode = inStrictMode;
+            // Even though in the AST the jsdoc @typedef node belongs to the current node,
+            // its symbol might be in the same scope with the current node's symbol. Consider:
+            //
+            //     /** @typedef {string | number} MyType */
+            //     function foo();
+            //
+            // Here the current node is "foo", which is a container, but the scope of "MyType" should
+            // not be inside "foo". Therefore we always bind @typedef before bind the parent node,
+            // and skip binding this tag later when binding all the other jsdoc tags.
+            if (ts.isInJavaScriptFile(node))
+                bindJSDocTypedefTagIfAny(node);
+            // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
+            // and then potentially add the symbol to an appropriate symbol table. Possible
+            // destination symbol tables are:
+            //
+            //  1) The 'exports' table of the current container's symbol.
+            //  2) The 'members' table of the current container's symbol.
+            //  3) The 'locals' table of the current container.
+            //
+            // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
+            // (like TypeLiterals for example) will not be put in any table.
+            bindWorker(node);
+            // Then we recurse into the children of the node to bind them as well. For certain
+            // symbols we do specialized work when we recurse. For example, we'll keep track of
+            // the current 'container' node when it changes. This helps us know which symbol table
+            // a local should go into for example. Since terminal nodes are known not to have
+            // children, as an optimization we don't process those.
+            if (node.kind > 142 /* LastToken */) {
+                var saveParent = parent;
+                parent = node;
+                var containerFlags = getContainerFlags(node);
+                if (containerFlags === 0 /* None */) {
+                    bindChildren(node);
+                }
+                else {
+                    bindContainer(node, containerFlags);
+                }
+                parent = saveParent;
+            }
+            else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) {
+                subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
+            }
+            inStrictMode = saveInStrictMode;
+        }
+        function bindJSDocTypedefTagIfAny(node) {
+            if (!ts.hasJSDocNodes(node)) {
+                return;
+            }
+            for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
+                var jsDoc = _a[_i];
+                if (!jsDoc.tags) {
+                    continue;
+                }
+                for (var _b = 0, _c = jsDoc.tags; _b < _c.length; _b++) {
+                    var tag = _c[_b];
+                    if (tag.kind === 283 /* JSDocTypedefTag */) {
+                        var savedParent = parent;
+                        parent = jsDoc;
+                        bind(tag);
+                        parent = savedParent;
+                    }
+                }
+            }
+        }
+        function updateStrictModeStatementList(statements) {
+            if (!inStrictMode) {
+                for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
+                    var statement = statements_1[_i];
+                    if (!ts.isPrologueDirective(statement)) {
+                        return;
+                    }
+                    if (isUseStrictPrologueDirective(statement)) {
+                        inStrictMode = true;
+                        return;
+                    }
+                }
+            }
+        }
+        /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
+        function isUseStrictPrologueDirective(node) {
+            var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
+            // Note: the node text must be exactly "use strict" or 'use strict'.  It is not ok for the
+            // string to contain unicode escapes (as per ES5).
+            return nodeText === '"use strict"' || nodeText === "'use strict'";
+        }
+        function bindWorker(node) {
+            switch (node.kind) {
+                /* Strict mode checks */
+                case 71 /* Identifier */:
+                    // for typedef type names with namespaces, bind the new jsdoc type symbol here
+                    // because it requires all containing namespaces to be in effect, namely the
+                    // current "blockScopeContainer" needs to be set to its immediate namespace parent.
+                    if (node.isInJSDocNamespace) {
+                        var parentNode = node.parent;
+                        while (parentNode && parentNode.kind !== 283 /* JSDocTypedefTag */) {
+                            parentNode = parentNode.parent;
+                        }
+                        bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
+                        break;
+                    }
+                // falls through
+                case 99 /* ThisKeyword */:
+                    if (currentFlow && (ts.isExpression(node) || parent.kind === 262 /* ShorthandPropertyAssignment */)) {
+                        node.flowNode = currentFlow;
+                    }
+                    return checkStrictModeIdentifier(node);
+                case 179 /* PropertyAccessExpression */:
+                    if (currentFlow && isNarrowableReference(node)) {
+                        node.flowNode = currentFlow;
+                    }
+                    break;
+                case 194 /* BinaryExpression */:
+                    var specialKind = ts.getSpecialPropertyAssignmentKind(node);
+                    switch (specialKind) {
+                        case 1 /* ExportsProperty */:
+                            bindExportsPropertyAssignment(node);
+                            break;
+                        case 2 /* ModuleExports */:
+                            bindModuleExportsAssignment(node);
+                            break;
+                        case 3 /* PrototypeProperty */:
+                            bindPrototypePropertyAssignment(node);
+                            break;
+                        case 4 /* ThisProperty */:
+                            bindThisPropertyAssignment(node);
+                            break;
+                        case 5 /* Property */:
+                            bindStaticPropertyAssignment(node);
+                            break;
+                        case 0 /* None */:
+                            // Nothing to do
+                            break;
+                        default:
+                            ts.Debug.fail("Unknown special property assignment kind");
+                    }
+                    return checkStrictModeBinaryExpression(node);
+                case 260 /* CatchClause */:
+                    return checkStrictModeCatchClause(node);
+                case 188 /* DeleteExpression */:
+                    return checkStrictModeDeleteExpression(node);
+                case 8 /* NumericLiteral */:
+                    return checkStrictModeNumericLiteral(node);
+                case 193 /* PostfixUnaryExpression */:
+                    return checkStrictModePostfixUnaryExpression(node);
+                case 192 /* PrefixUnaryExpression */:
+                    return checkStrictModePrefixUnaryExpression(node);
+                case 220 /* WithStatement */:
+                    return checkStrictModeWithStatement(node);
+                case 169 /* ThisType */:
+                    seenThisKeyword = true;
+                    return;
+                case 158 /* TypePredicate */:
+                    return checkTypePredicate(node);
+                case 145 /* TypeParameter */:
+                    return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530920 /* TypeParameterExcludes */);
+                case 146 /* Parameter */:
+                    return bindParameter(node);
+                case 226 /* VariableDeclaration */:
+                    return bindVariableDeclarationOrBindingElement(node);
+                case 176 /* BindingElement */:
+                    node.flowNode = currentFlow;
+                    return bindVariableDeclarationOrBindingElement(node);
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    return bindPropertyWorker(node);
+                case 261 /* PropertyAssignment */:
+                case 262 /* ShorthandPropertyAssignment */:
+                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
+                case 264 /* EnumMember */:
+                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 900095 /* EnumMemberExcludes */);
+                case 155 /* CallSignature */:
+                case 156 /* ConstructSignature */:
+                case 157 /* IndexSignature */:
+                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                    // If this is an ObjectLiteralExpression method, then it sits in the same space
+                    // as other properties in the object literal.  So we use SymbolFlags.PropertyExcludes
+                    // so that it will conflict with any other object literal members with the same
+                    // name.
+                    return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
+                case 228 /* FunctionDeclaration */:
+                    return bindFunctionDeclaration(node);
+                case 152 /* Constructor */:
+                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
+                case 153 /* GetAccessor */:
+                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
+                case 154 /* SetAccessor */:
+                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
+                case 160 /* FunctionType */:
+                case 273 /* JSDocFunctionType */:
+                case 161 /* ConstructorType */:
+                    return bindFunctionOrConstructorType(node);
+                case 163 /* TypeLiteral */:
+                case 285 /* JSDocTypeLiteral */:
+                case 172 /* MappedType */:
+                    return bindAnonymousTypeWorker(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return bindObjectLiteralExpression(node);
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    return bindFunctionExpression(node);
+                case 181 /* CallExpression */:
+                    if (ts.isInJavaScriptFile(node)) {
+                        bindCallExpression(node);
+                    }
+                    break;
+                // Members of classes, interfaces, and modules
+                case 199 /* ClassExpression */:
+                case 229 /* ClassDeclaration */:
+                    // All classes are automatically in strict mode in ES6.
+                    inStrictMode = true;
+                    return bindClassLikeDeclaration(node);
+                case 230 /* InterfaceDeclaration */:
+                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 792968 /* InterfaceExcludes */);
+                case 231 /* TypeAliasDeclaration */:
+                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
+                case 232 /* EnumDeclaration */:
+                    return bindEnumDeclaration(node);
+                case 233 /* ModuleDeclaration */:
+                    return bindModuleDeclaration(node);
+                // Jsx-attributes
+                case 254 /* JsxAttributes */:
+                    return bindJsxAttributes(node);
+                case 253 /* JsxAttribute */:
+                    return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */);
+                // Imports and exports
+                case 237 /* ImportEqualsDeclaration */:
+                case 240 /* NamespaceImport */:
+                case 242 /* ImportSpecifier */:
+                case 246 /* ExportSpecifier */:
+                    return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
+                case 236 /* NamespaceExportDeclaration */:
+                    return bindNamespaceExportDeclaration(node);
+                case 239 /* ImportClause */:
+                    return bindImportClause(node);
+                case 244 /* ExportDeclaration */:
+                    return bindExportDeclaration(node);
+                case 243 /* ExportAssignment */:
+                    return bindExportAssignment(node);
+                case 265 /* SourceFile */:
+                    updateStrictModeStatementList(node.statements);
+                    return bindSourceFileIfExternalModule();
+                case 207 /* Block */:
+                    if (!ts.isFunctionLike(node.parent)) {
+                        return;
+                    }
+                // falls through
+                case 234 /* ModuleBlock */:
+                    return updateStrictModeStatementList(node.statements);
+                case 279 /* JSDocParameterTag */:
+                    if (node.parent.kind !== 285 /* JSDocTypeLiteral */) {
+                        break;
+                    }
+                // falls through
+                case 284 /* JSDocPropertyTag */:
+                    var propTag = node;
+                    var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 272 /* JSDocOptionalType */ ?
+                        4 /* Property */ | 16777216 /* Optional */ :
+                        4 /* Property */;
+                    return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */);
+                case 283 /* JSDocTypedefTag */: {
+                    var fullName = node.fullName;
+                    if (!fullName || fullName.kind === 71 /* Identifier */) {
+                        return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
+                    }
+                    break;
+                }
+            }
+        }
+        function bindPropertyWorker(node) {
+            return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
+        }
+        function bindAnonymousTypeWorker(node) {
+            return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */);
+        }
+        function checkTypePredicate(node) {
+            var parameterName = node.parameterName, type = node.type;
+            if (parameterName && parameterName.kind === 71 /* Identifier */) {
+                checkStrictModeIdentifier(parameterName);
+            }
+            if (parameterName && parameterName.kind === 169 /* ThisType */) {
+                seenThisKeyword = true;
+            }
+            bind(type);
+        }
+        function bindSourceFileIfExternalModule() {
+            setExportContextFlag(file);
+            if (ts.isExternalModule(file)) {
+                bindSourceFileAsExternalModule();
+            }
+        }
+        function bindSourceFileAsExternalModule() {
+            bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+        }
+        function bindExportAssignment(node) {
+            if (!container.symbol || !container.symbol.exports) {
+                // Export assignment in some sort of block construct
+                bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node));
+            }
+            else {
+                // An export default clause with an expression exports a value
+                // We want to exclude both class and function here,  this is necessary to issue an error when there are both
+                // default export-assignment and default export function and class declaration.
+                var flags = node.kind === 243 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node)
+                    // An export default clause with an EntityNameExpression exports all meanings of that identifier
+                    ? 2097152 /* Alias */
+                    // An export default clause with any other expression exports a value
+                    : 4 /* Property */;
+                declareSymbol(container.symbol.exports, container.symbol, node, flags, 4 /* Property */ | 2097152 /* AliasExcludes */ | 32 /* Class */ | 16 /* Function */);
+            }
+        }
+        function bindNamespaceExportDeclaration(node) {
+            if (node.modifiers && node.modifiers.length) {
+                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
+            }
+            if (node.parent.kind !== 265 /* SourceFile */) {
+                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level));
+                return;
+            }
+            else {
+                var parent_1 = node.parent;
+                if (!ts.isExternalModule(parent_1)) {
+                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files));
+                    return;
+                }
+                if (!parent_1.isDeclarationFile) {
+                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files));
+                    return;
+                }
+            }
+            file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable();
+            declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
+        }
+        function bindExportDeclaration(node) {
+            if (!container.symbol || !container.symbol.exports) {
+                // Export * in some sort of block construct
+                bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node));
+            }
+            else if (!node.exportClause) {
+                // All export * declarations are collected in an __export symbol
+                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */);
+            }
+        }
+        function bindImportClause(node) {
+            if (node.name) {
+                declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
+            }
+        }
+        function setCommonJsModuleIndicator(node) {
+            if (!file.commonJsModuleIndicator) {
+                file.commonJsModuleIndicator = node;
+                if (!file.externalModuleIndicator) {
+                    bindSourceFileAsExternalModule();
+                }
+            }
+        }
+        function bindExportsPropertyAssignment(node) {
+            // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
+            // expression is the declaration
+            setCommonJsModuleIndicator(node);
+            declareSymbol(file.symbol.exports, file.symbol, node.left, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */);
+        }
+        function isExportsOrModuleExportsOrAlias(node) {
+            return ts.isExportsIdentifier(node) ||
+                ts.isModuleExportsPropertyAccessExpression(node) ||
+                ts.isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node);
+        }
+        function isNameOfExportsOrModuleExportsAliasDeclaration(node) {
+            var symbol = lookupSymbolForName(node.escapedText);
+            return symbol && symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) &&
+                symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
+        }
+        function isExportsOrModuleExportsOrAliasOrAssignment(node) {
+            return isExportsOrModuleExportsOrAlias(node) ||
+                (ts.isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right)));
+        }
+        function bindModuleExportsAssignment(node) {
+            // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
+            // is still pointing to 'module.exports'.
+            // We do not want to consider this as 'export=' since a module can have only one of these.
+            // Similarly we do not want to treat 'module.exports = exports' as an 'export='.
+            var assignedExpression = ts.getRightMostAssignedExpression(node.right);
+            if (ts.isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
+                // Mark it as a module in case there are no other exports in the file
+                setCommonJsModuleIndicator(node);
+                return;
+            }
+            // 'module.exports = expr' assignment
+            setCommonJsModuleIndicator(node);
+            declareSymbol(file.symbol.exports, file.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */, 0 /* None */);
+        }
+        function bindThisPropertyAssignment(node) {
+            ts.Debug.assert(ts.isInJavaScriptFile(node));
+            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
+            switch (container.kind) {
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                    // Declare a 'member' if the container is an ES5 class or ES6 constructor
+                    container.symbol.members = container.symbol.members || ts.createSymbolTable();
+                    // It's acceptable for multiple 'this' assignments of the same identifier to occur
+                    declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */);
+                    break;
+                case 152 /* Constructor */:
+                case 149 /* PropertyDeclaration */:
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    // this.foo assignment in a JavaScript class
+                    // Bind this property to the containing class
+                    var containingClass = container.parent;
+                    var symbolTable = ts.hasModifier(container, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members;
+                    declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */, 0 /* None */, /*isReplaceableByMethod*/ true);
+                    break;
+            }
+        }
+        function bindPrototypePropertyAssignment(node) {
+            // We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x was a function.
+            // Look up the function in the local scope, since prototype assignments should
+            // follow the function declaration
+            var leftSideOfAssignment = node.left;
+            var classPrototype = leftSideOfAssignment.expression;
+            var constructorFunction = classPrototype.expression;
+            // Fix up parent pointers since we're going to use these nodes before we bind into them
+            leftSideOfAssignment.parent = node;
+            constructorFunction.parent = classPrototype;
+            classPrototype.parent = leftSideOfAssignment;
+            bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
+        }
+        function bindStaticPropertyAssignment(node) {
+            // We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function.
+            // Look up the function in the local scope, since prototype assignments should
+            // follow the function declaration
+            var leftSideOfAssignment = node.left;
+            var target = leftSideOfAssignment.expression;
+            if (ts.isIdentifier(target)) {
+                // Fix up parent pointers since we're going to use these nodes before we bind into them
+                leftSideOfAssignment.parent = node;
+                target.parent = leftSideOfAssignment;
+                if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
+                    // This can be an alias for the 'exports' or 'module.exports' names, e.g.
+                    //    var util = module.exports;
+                    //    util.property = function ...
+                    bindExportsPropertyAssignment(node);
+                }
+                else {
+                    bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
+                }
+            }
+        }
+        function lookupSymbolForName(name) {
+            return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
+        }
+        function bindPropertyAssignment(functionName, propertyAccessExpression, isPrototypeProperty) {
+            var targetSymbol = lookupSymbolForName(functionName);
+            if (targetSymbol && ts.isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
+                targetSymbol = targetSymbol.valueDeclaration.initializer.symbol;
+            }
+            if (!targetSymbol || !(targetSymbol.flags & (16 /* Function */ | 32 /* Class */))) {
+                return;
+            }
+            // Set up the members collection if it doesn't exist already
+            var symbolTable = isPrototypeProperty ?
+                (targetSymbol.members || (targetSymbol.members = ts.createSymbolTable())) :
+                (targetSymbol.exports || (targetSymbol.exports = ts.createSymbolTable()));
+            // Declare the method/property
+            declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, 4 /* Property */, 0 /* PropertyExcludes */);
+        }
+        function bindCallExpression(node) {
+            // We're only inspecting call expressions to detect CommonJS modules, so we can skip
+            // this check if we've already seen the module indicator
+            if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) {
+                setCommonJsModuleIndicator(node);
+            }
+        }
+        function bindClassLikeDeclaration(node) {
+            if (node.kind === 229 /* ClassDeclaration */) {
+                bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
+            }
+            else {
+                var bindingName = node.name ? node.name.escapedText : "__class" /* Class */;
+                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
+                // Add name of class expression into the map for semantic classifier
+                if (node.name) {
+                    classifiableNames.set(node.name.escapedText, true);
+                }
+            }
+            var symbol = node.symbol;
+            // TypeScript 1.0 spec (April 2014): 8.4
+            // Every class automatically contains a static property member named 'prototype', the
+            // type of which is an instantiation of the class type with type Any supplied as a type
+            // argument for each type parameter. It is an error to explicitly declare a static
+            // property member with the name 'prototype'.
+            //
+            // Note: we check for this here because this class may be merging into a module.  The
+            // module might have an exported variable called 'prototype'.  We can't allow that as
+            // that would clash with the built-in 'prototype' for the class.
+            var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype");
+            var symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
+            if (symbolExport) {
+                if (node.name) {
+                    node.name.parent = node;
+                }
+                file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol)));
+            }
+            symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
+            prototypeSymbol.parent = symbol;
+        }
+        function bindEnumDeclaration(node) {
+            return ts.isConst(node)
+                ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
+                : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
+        }
+        function bindVariableDeclarationOrBindingElement(node) {
+            if (inStrictMode) {
+                checkStrictModeEvalOrArguments(node, node.name);
+            }
+            if (!ts.isBindingPattern(node.name)) {
+                if (ts.isBlockOrCatchScoped(node)) {
+                    bindBlockScopedVariableDeclaration(node);
+                }
+                else if (ts.isParameterDeclaration(node)) {
+                    // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
+                    // because its parent chain has already been set up, since parents are set before descending into children.
+                    //
+                    // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
+                    // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
+                    // For example:
+                    //      function foo([a,a]) {} // Duplicate Identifier error
+                    //      function bar(a,a) {}   // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
+                    //                             // which correctly set excluded symbols
+                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
+                }
+                else {
+                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
+                }
+            }
+        }
+        function bindParameter(node) {
+            if (inStrictMode && !ts.isInAmbientContext(node)) {
+                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
+                // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
+                checkStrictModeEvalOrArguments(node, node.name);
+            }
+            if (ts.isBindingPattern(node.name)) {
+                bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + ts.indexOf(node.parent.parameters, node));
+            }
+            else {
+                declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
+            }
+            // If this is a property-parameter, then also declare the property symbol into the
+            // containing class.
+            if (ts.isParameterPropertyDeclaration(node)) {
+                var classDeclaration = node.parent.parent;
+                declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
+            }
+        }
+        function bindFunctionDeclaration(node) {
+            if (!file.isDeclarationFile && !ts.isInAmbientContext(node)) {
+                if (ts.isAsyncFunction(node)) {
+                    emitFlags |= 1024 /* HasAsyncFunctions */;
+                }
+            }
+            checkStrictModeFunctionName(node);
+            if (inStrictMode) {
+                checkStrictModeFunctionDeclaration(node);
+                bindBlockScopedDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */);
+            }
+            else {
+                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
+            }
+        }
+        function bindFunctionExpression(node) {
+            if (!file.isDeclarationFile && !ts.isInAmbientContext(node)) {
+                if (ts.isAsyncFunction(node)) {
+                    emitFlags |= 1024 /* HasAsyncFunctions */;
+                }
+            }
+            if (currentFlow) {
+                node.flowNode = currentFlow;
+            }
+            checkStrictModeFunctionName(node);
+            var bindingName = node.name ? node.name.escapedText : "__function" /* Function */;
+            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
+        }
+        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
+            if (!file.isDeclarationFile && !ts.isInAmbientContext(node) && ts.isAsyncFunction(node)) {
+                emitFlags |= 1024 /* HasAsyncFunctions */;
+            }
+            if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) {
+                node.flowNode = currentFlow;
+            }
+            return ts.hasDynamicName(node)
+                ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */)
+                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
+        }
+        // reachability checks
+        function shouldReportErrorOnModuleDeclaration(node) {
+            var instanceState = getModuleInstanceState(node);
+            return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
+        }
+        function checkUnreachable(node) {
+            if (!(currentFlow.flags & 1 /* Unreachable */)) {
+                return false;
+            }
+            if (currentFlow === unreachableFlow) {
+                var reportError = 
+                // report error on all statements except empty ones
+                (ts.isStatementButNotDeclaration(node) && node.kind !== 209 /* EmptyStatement */) ||
+                    // report error on class declarations
+                    node.kind === 229 /* ClassDeclaration */ ||
+                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
+                    (node.kind === 233 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
+                    // report error on regular enums and const enums if preserveConstEnums is set
+                    (node.kind === 232 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
+                if (reportError) {
+                    currentFlow = reportedUnreachableFlow;
+                    // unreachable code is reported if
+                    // - user has explicitly asked about it AND
+                    // - statement is in not ambient context (statements in ambient context is already an error
+                    //   so we should not report extras) AND
+                    //   - node is not variable statement OR
+                    //   - node is block scoped variable statement OR
+                    //   - node is not block scoped variable statement and at least one variable declaration has initializer
+                    //   Rationale: we don't want to report errors on non-initialized var's since they are hoisted
+                    //   On the other side we do want to report errors on non-initialized 'lets' because of TDZ
+                    var reportUnreachableCode = !options.allowUnreachableCode &&
+                        !ts.isInAmbientContext(node) &&
+                        (node.kind !== 208 /* VariableStatement */ ||
+                            ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */ ||
+                            ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
+                    if (reportUnreachableCode) {
+                        errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+    /**
+     * Computes the transform flags for a node, given the transform flags of its subtree
+     *
+     * @param node The node to analyze
+     * @param subtreeFlags Transform flags computed for this node's subtree
+     */
+    function computeTransformFlagsForNode(node, subtreeFlags) {
+        var kind = node.kind;
+        switch (kind) {
+            case 181 /* CallExpression */:
+                return computeCallExpression(node, subtreeFlags);
+            case 182 /* NewExpression */:
+                return computeNewExpression(node, subtreeFlags);
+            case 233 /* ModuleDeclaration */:
+                return computeModuleDeclaration(node, subtreeFlags);
+            case 185 /* ParenthesizedExpression */:
+                return computeParenthesizedExpression(node, subtreeFlags);
+            case 194 /* BinaryExpression */:
+                return computeBinaryExpression(node, subtreeFlags);
+            case 210 /* ExpressionStatement */:
+                return computeExpressionStatement(node, subtreeFlags);
+            case 146 /* Parameter */:
+                return computeParameter(node, subtreeFlags);
+            case 187 /* ArrowFunction */:
+                return computeArrowFunction(node, subtreeFlags);
+            case 186 /* FunctionExpression */:
+                return computeFunctionExpression(node, subtreeFlags);
+            case 228 /* FunctionDeclaration */:
+                return computeFunctionDeclaration(node, subtreeFlags);
+            case 226 /* VariableDeclaration */:
+                return computeVariableDeclaration(node, subtreeFlags);
+            case 227 /* VariableDeclarationList */:
+                return computeVariableDeclarationList(node, subtreeFlags);
+            case 208 /* VariableStatement */:
+                return computeVariableStatement(node, subtreeFlags);
+            case 222 /* LabeledStatement */:
+                return computeLabeledStatement(node, subtreeFlags);
+            case 229 /* ClassDeclaration */:
+                return computeClassDeclaration(node, subtreeFlags);
+            case 199 /* ClassExpression */:
+                return computeClassExpression(node, subtreeFlags);
+            case 259 /* HeritageClause */:
+                return computeHeritageClause(node, subtreeFlags);
+            case 260 /* CatchClause */:
+                return computeCatchClause(node, subtreeFlags);
+            case 201 /* ExpressionWithTypeArguments */:
+                return computeExpressionWithTypeArguments(node, subtreeFlags);
+            case 152 /* Constructor */:
+                return computeConstructor(node, subtreeFlags);
+            case 149 /* PropertyDeclaration */:
+                return computePropertyDeclaration(node, subtreeFlags);
+            case 151 /* MethodDeclaration */:
+                return computeMethod(node, subtreeFlags);
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+                return computeAccessor(node, subtreeFlags);
+            case 237 /* ImportEqualsDeclaration */:
+                return computeImportEquals(node, subtreeFlags);
+            case 179 /* PropertyAccessExpression */:
+                return computePropertyAccess(node, subtreeFlags);
+            default:
+                return computeOther(node, kind, subtreeFlags);
+        }
+    }
+    ts.computeTransformFlagsForNode = computeTransformFlagsForNode;
+    function computeCallExpression(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        var expression = node.expression;
+        var expressionKind = expression.kind;
+        if (node.typeArguments) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        if (subtreeFlags & 524288 /* ContainsSpread */
+            || isSuperOrSuperProperty(expression, expressionKind)) {
+            // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
+            // node.
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        if (expression.kind === 91 /* ImportKeyword */) {
+            transformFlags |= 67108864 /* ContainsDynamicImport */;
+            // A dynamic 'import()' call that contains a lexical 'this' will
+            // require a captured 'this' when emitting down-level.
+            if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
+                transformFlags |= 32768 /* ContainsCapturedLexicalThis */;
+            }
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */;
+    }
+    function isSuperOrSuperProperty(node, kind) {
+        switch (kind) {
+            case 97 /* SuperKeyword */:
+                return true;
+            case 179 /* PropertyAccessExpression */:
+            case 180 /* ElementAccessExpression */:
+                var expression = node.expression;
+                var expressionKind = expression.kind;
+                return expressionKind === 97 /* SuperKeyword */;
+        }
+        return false;
+    }
+    function computeNewExpression(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        if (node.typeArguments) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        if (subtreeFlags & 524288 /* ContainsSpread */) {
+            // If the this node contains a SpreadElementExpression then it is an ES6
+            // node.
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */;
+    }
+    function computeBinaryExpression(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        var operatorTokenKind = node.operatorToken.kind;
+        var leftKind = node.left.kind;
+        if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 178 /* ObjectLiteralExpression */) {
+            // Destructuring object assignments with are ES2015 syntax
+            // and possibly ESNext if they contain rest
+            transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */;
+        }
+        else if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 177 /* ArrayLiteralExpression */) {
+            // Destructuring assignments are ES2015 syntax.
+            transformFlags |= 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */;
+        }
+        else if (operatorTokenKind === 40 /* AsteriskAsteriskToken */
+            || operatorTokenKind === 62 /* AsteriskAsteriskEqualsToken */) {
+            // Exponentiation is ES2016 syntax.
+            transformFlags |= 32 /* AssertES2016 */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeParameter(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        var name = node.name;
+        var initializer = node.initializer;
+        var dotDotDotToken = node.dotDotDotToken;
+        // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
+        // syntax.
+        if (node.questionToken
+            || node.type
+            || subtreeFlags & 4096 /* ContainsDecorators */
+            || ts.isThisIdentifier(name)) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // If a parameter has an accessibility modifier, then it is TypeScript syntax.
+        if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
+            transformFlags |= 3 /* AssertTypeScript */ | 262144 /* ContainsParameterPropertyAssignments */;
+        }
+        // parameters with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
+        // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
+        if (subtreeFlags & 8388608 /* ContainsBindingPattern */ || initializer || dotDotDotToken) {
+            transformFlags |= 192 /* AssertES2015 */ | 131072 /* ContainsDefaultValueAssignments */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* ParameterExcludes */;
+    }
+    function computeParenthesizedExpression(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        var expression = node.expression;
+        var expressionKind = expression.kind;
+        var expressionTransformFlags = expression.transformFlags;
+        // If the node is synthesized, it means the emitter put the parentheses there,
+        // not the user. If we didn't want them, the emitter would not have put them
+        // there.
+        if (expressionKind === 202 /* AsExpression */
+            || expressionKind === 184 /* TypeAssertionExpression */) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // If the expression of a ParenthesizedExpression is a destructuring assignment,
+        // then the ParenthesizedExpression is a destructuring assignment.
+        if (expressionTransformFlags & 1024 /* DestructuringAssignment */) {
+            transformFlags |= 1024 /* DestructuringAssignment */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeClassDeclaration(node, subtreeFlags) {
+        var transformFlags;
+        if (ts.hasModifier(node, 2 /* Ambient */)) {
+            // An ambient declaration is TypeScript syntax.
+            transformFlags = 3 /* AssertTypeScript */;
+        }
+        else {
+            // A ClassDeclaration is ES6 syntax.
+            transformFlags = subtreeFlags | 192 /* AssertES2015 */;
+            // A class with a parameter property assignment, property initializer, or decorator is
+            // TypeScript syntax.
+            // An exported declaration may be TypeScript syntax, but is handled by the visitor
+            // for a namespace declaration.
+            if ((subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */)
+                || node.typeParameters) {
+                transformFlags |= 3 /* AssertTypeScript */;
+            }
+            if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
+                // A computed property name containing `this` might need to be rewritten,
+                // so propagate the ContainsLexicalThis flag upward.
+                transformFlags |= 16384 /* ContainsLexicalThis */;
+            }
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~539358529 /* ClassExcludes */;
+    }
+    function computeClassExpression(node, subtreeFlags) {
+        // A ClassExpression is ES6 syntax.
+        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
+        // A class with a parameter property assignment, property initializer, or decorator is
+        // TypeScript syntax.
+        if (subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */
+            || node.typeParameters) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
+            // A computed property name containing `this` might need to be rewritten,
+            // so propagate the ContainsLexicalThis flag upward.
+            transformFlags |= 16384 /* ContainsLexicalThis */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~539358529 /* ClassExcludes */;
+    }
+    function computeHeritageClause(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        switch (node.token) {
+            case 85 /* ExtendsKeyword */:
+                // An `extends` HeritageClause is ES6 syntax.
+                transformFlags |= 192 /* AssertES2015 */;
+                break;
+            case 108 /* ImplementsKeyword */:
+                // An `implements` HeritageClause is TypeScript syntax.
+                transformFlags |= 3 /* AssertTypeScript */;
+                break;
+            default:
+                ts.Debug.fail("Unexpected token for heritage clause");
+                break;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeCatchClause(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        if (!node.variableDeclaration) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        else if (ts.isBindingPattern(node.variableDeclaration.name)) {
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~537920833 /* CatchClauseExcludes */;
+    }
+    function computeExpressionWithTypeArguments(node, subtreeFlags) {
+        // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
+        // extends clause of a class.
+        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
+        // If an ExpressionWithTypeArguments contains type arguments, then it
+        // is TypeScript syntax.
+        if (node.typeArguments) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeConstructor(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // TypeScript-specific modifiers and overloads are TypeScript syntax
+        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
+            || !node.body) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // function declarations with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601015617 /* ConstructorExcludes */;
+    }
+    function computeMethod(node, subtreeFlags) {
+        // A MethodDeclaration is ES6 syntax.
+        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
+        // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
+        // overloads are TypeScript syntax.
+        if (node.decorators
+            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
+            || node.typeParameters
+            || node.type
+            || !node.body) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // function declarations with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        // An async method declaration is ES2017 syntax.
+        if (ts.hasModifier(node, 256 /* Async */)) {
+            transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
+        }
+        if (node.asteriskToken) {
+            transformFlags |= 768 /* AssertGenerator */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601015617 /* MethodOrAccessorExcludes */;
+    }
+    function computeAccessor(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // Decorators, TypeScript-specific modifiers, type annotations, and overloads are
+        // TypeScript syntax.
+        if (node.decorators
+            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
+            || node.type
+            || !node.body) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // function declarations with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601015617 /* MethodOrAccessorExcludes */;
+    }
+    function computePropertyDeclaration(node, subtreeFlags) {
+        // A PropertyDeclaration is TypeScript syntax.
+        var transformFlags = subtreeFlags | 3 /* AssertTypeScript */;
+        // If the PropertyDeclaration has an initializer, we need to inform its ancestor
+        // so that it handle the transformation.
+        if (node.initializer) {
+            transformFlags |= 8192 /* ContainsPropertyInitializer */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeFunctionDeclaration(node, subtreeFlags) {
+        var transformFlags;
+        var modifierFlags = ts.getModifierFlags(node);
+        var body = node.body;
+        if (!body || (modifierFlags & 2 /* Ambient */)) {
+            // An ambient declaration is TypeScript syntax.
+            // A FunctionDeclaration without a body is an overload and is TypeScript syntax.
+            transformFlags = 3 /* AssertTypeScript */;
+        }
+        else {
+            transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */;
+            // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
+            // syntax.
+            if (modifierFlags & 2270 /* TypeScriptModifier */
+                || node.typeParameters
+                || node.type) {
+                transformFlags |= 3 /* AssertTypeScript */;
+            }
+            // An async function declaration is ES2017 syntax.
+            if (modifierFlags & 256 /* Async */) {
+                transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
+            }
+            // function declarations with object rest destructuring are ES Next syntax
+            if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+                transformFlags |= 8 /* AssertESNext */;
+            }
+            // If a FunctionDeclaration's subtree has marked the container as needing to capture the
+            // lexical this, or the function contains parameters with initializers, then this node is
+            // ES6 syntax.
+            if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) {
+                transformFlags |= 192 /* AssertES2015 */;
+            }
+            // If a FunctionDeclaration is generator function and is the body of a
+            // transformed async function, then this node can be transformed to a
+            // down-level generator.
+            // Currently we do not support transforming any other generator fucntions
+            // down level.
+            if (node.asteriskToken) {
+                transformFlags |= 768 /* AssertGenerator */;
+            }
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601281857 /* FunctionExcludes */;
+    }
+    function computeFunctionExpression(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
+        // syntax.
+        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
+            || node.typeParameters
+            || node.type) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // An async function expression is ES2017 syntax.
+        if (ts.hasModifier(node, 256 /* Async */)) {
+            transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
+        }
+        // function expressions with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        // If a FunctionExpression's subtree has marked the container as needing to capture the
+        // lexical this, or the function contains parameters with initializers, then this node is
+        // ES6 syntax.
+        if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) {
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        // If a FunctionExpression is generator function and is the body of a
+        // transformed async function, then this node can be transformed to a
+        // down-level generator.
+        if (node.asteriskToken) {
+            transformFlags |= 768 /* AssertGenerator */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601281857 /* FunctionExcludes */;
+    }
+    function computeArrowFunction(node, subtreeFlags) {
+        // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
+        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
+        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
+        // syntax.
+        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
+            || node.typeParameters
+            || node.type) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        // An async arrow function is ES2017 syntax.
+        if (ts.hasModifier(node, 256 /* Async */)) {
+            transformFlags |= 16 /* AssertES2017 */;
+        }
+        // arrow functions with object rest destructuring are ES Next syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        // If an ArrowFunction contains a lexical this, its container must capture the lexical this.
+        if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
+            transformFlags |= 32768 /* ContainsCapturedLexicalThis */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~601249089 /* ArrowFunctionExcludes */;
+    }
+    function computePropertyAccess(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        var expression = node.expression;
+        var expressionKind = expression.kind;
+        // If a PropertyAccessExpression starts with a super keyword, then it is
+        // ES6 syntax, and requires a lexical `this` binding.
+        if (expressionKind === 97 /* SuperKeyword */) {
+            transformFlags |= 16384 /* ContainsLexicalThis */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeVariableDeclaration(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
+        // A VariableDeclaration containing ObjectRest is ESNext syntax
+        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
+            transformFlags |= 8 /* AssertESNext */;
+        }
+        // Type annotations are TypeScript syntax.
+        if (node.type) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeVariableStatement(node, subtreeFlags) {
+        var transformFlags;
+        var declarationListTransformFlags = node.declarationList.transformFlags;
+        // An ambient declaration is TypeScript syntax.
+        if (ts.hasModifier(node, 2 /* Ambient */)) {
+            transformFlags = 3 /* AssertTypeScript */;
+        }
+        else {
+            transformFlags = subtreeFlags;
+            if (declarationListTransformFlags & 8388608 /* ContainsBindingPattern */) {
+                transformFlags |= 192 /* AssertES2015 */;
+            }
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeLabeledStatement(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
+        if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */
+            && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeImportEquals(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // An ImportEqualsDeclaration with a namespace reference is TypeScript.
+        if (!ts.isExternalModuleImportEqualsDeclaration(node)) {
+            transformFlags |= 3 /* AssertTypeScript */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeExpressionStatement(node, subtreeFlags) {
+        var transformFlags = subtreeFlags;
+        // If the expression of an expression statement is a destructuring assignment,
+        // then we treat the statement as ES6 so that we can indicate that we do not
+        // need to hold on to the right-hand side.
+        if (node.expression.transformFlags & 1024 /* DestructuringAssignment */) {
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~536872257 /* NodeExcludes */;
+    }
+    function computeModuleDeclaration(node, subtreeFlags) {
+        var transformFlags = 3 /* AssertTypeScript */;
+        var modifierFlags = ts.getModifierFlags(node);
+        if ((modifierFlags & 2 /* Ambient */) === 0) {
+            transformFlags |= subtreeFlags;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~574674241 /* ModuleExcludes */;
+    }
+    function computeVariableDeclarationList(node, subtreeFlags) {
+        var transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */;
+        if (subtreeFlags & 8388608 /* ContainsBindingPattern */) {
+            transformFlags |= 192 /* AssertES2015 */;
+        }
+        // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
+        if (node.flags & 3 /* BlockScoped */) {
+            transformFlags |= 192 /* AssertES2015 */ | 4194304 /* ContainsBlockScopedBinding */;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~546309441 /* VariableDeclarationListExcludes */;
+    }
+    function computeOther(node, kind, subtreeFlags) {
+        // Mark transformations needed for each node
+        var transformFlags = subtreeFlags;
+        var excludeFlags = 536872257 /* NodeExcludes */;
+        switch (kind) {
+            case 120 /* AsyncKeyword */:
+            case 191 /* AwaitExpression */:
+                // async/await is ES2017 syntax, but may be ESNext syntax (for async generators)
+                transformFlags |= 8 /* AssertESNext */ | 16 /* AssertES2017 */;
+                break;
+            case 114 /* PublicKeyword */:
+            case 112 /* PrivateKeyword */:
+            case 113 /* ProtectedKeyword */:
+            case 117 /* AbstractKeyword */:
+            case 124 /* DeclareKeyword */:
+            case 76 /* ConstKeyword */:
+            case 232 /* EnumDeclaration */:
+            case 264 /* EnumMember */:
+            case 184 /* TypeAssertionExpression */:
+            case 202 /* AsExpression */:
+            case 203 /* NonNullExpression */:
+            case 131 /* ReadonlyKeyword */:
+                // These nodes are TypeScript syntax.
+                transformFlags |= 3 /* AssertTypeScript */;
+                break;
+            case 249 /* JsxElement */:
+            case 250 /* JsxSelfClosingElement */:
+            case 251 /* JsxOpeningElement */:
+            case 10 /* JsxText */:
+            case 252 /* JsxClosingElement */:
+            case 253 /* JsxAttribute */:
+            case 254 /* JsxAttributes */:
+            case 255 /* JsxSpreadAttribute */:
+            case 256 /* JsxExpression */:
+                // These nodes are Jsx syntax.
+                transformFlags |= 4 /* AssertJsx */;
+                break;
+            case 13 /* NoSubstitutionTemplateLiteral */:
+            case 14 /* TemplateHead */:
+            case 15 /* TemplateMiddle */:
+            case 16 /* TemplateTail */:
+            case 196 /* TemplateExpression */:
+            case 183 /* TaggedTemplateExpression */:
+            case 262 /* ShorthandPropertyAssignment */:
+            case 115 /* StaticKeyword */:
+            case 204 /* MetaProperty */:
+                // These nodes are ES6 syntax.
+                transformFlags |= 192 /* AssertES2015 */;
+                break;
+            case 9 /* StringLiteral */:
+                if (node.hasExtendedUnicodeEscape) {
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                break;
+            case 8 /* NumericLiteral */:
+                if (node.numericLiteralFlags & 48 /* BinaryOrOctalSpecifier */) {
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                break;
+            case 216 /* ForOfStatement */:
+                // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
+                if (node.awaitModifier) {
+                    transformFlags |= 8 /* AssertESNext */;
+                }
+                transformFlags |= 192 /* AssertES2015 */;
+                break;
+            case 197 /* YieldExpression */:
+                // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
+                // generator).
+                transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 16777216 /* ContainsYield */;
+                break;
+            case 119 /* AnyKeyword */:
+            case 133 /* NumberKeyword */:
+            case 130 /* NeverKeyword */:
+            case 134 /* ObjectKeyword */:
+            case 136 /* StringKeyword */:
+            case 122 /* BooleanKeyword */:
+            case 137 /* SymbolKeyword */:
+            case 105 /* VoidKeyword */:
+            case 145 /* TypeParameter */:
+            case 148 /* PropertySignature */:
+            case 150 /* MethodSignature */:
+            case 155 /* CallSignature */:
+            case 156 /* ConstructSignature */:
+            case 157 /* IndexSignature */:
+            case 158 /* TypePredicate */:
+            case 159 /* TypeReference */:
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+            case 162 /* TypeQuery */:
+            case 163 /* TypeLiteral */:
+            case 164 /* ArrayType */:
+            case 165 /* TupleType */:
+            case 166 /* UnionType */:
+            case 167 /* IntersectionType */:
+            case 168 /* ParenthesizedType */:
+            case 230 /* InterfaceDeclaration */:
+            case 231 /* TypeAliasDeclaration */:
+            case 169 /* ThisType */:
+            case 170 /* TypeOperator */:
+            case 171 /* IndexedAccessType */:
+            case 172 /* MappedType */:
+            case 173 /* LiteralType */:
+            case 236 /* NamespaceExportDeclaration */:
+                // Types and signatures are TypeScript syntax, and exclude all other facts.
+                transformFlags = 3 /* AssertTypeScript */;
+                excludeFlags = -3 /* TypeExcludes */;
+                break;
+            case 144 /* ComputedPropertyName */:
+                // Even though computed property names are ES6, we don't treat them as such.
+                // This is so that they can flow through PropertyName transforms unaffected.
+                // Instead, we mark the container as ES6, so that it can properly handle the transform.
+                transformFlags |= 2097152 /* ContainsComputedPropertyName */;
+                if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
+                    // A computed method name like `[this.getName()](x: string) { ... }` needs to
+                    // distinguish itself from the normal case of a method body containing `this`:
+                    // `this` inside a method doesn't need to be rewritten (the method provides `this`),
+                    // whereas `this` inside a computed name *might* need to be rewritten if the class/object
+                    // is inside an arrow function:
+                    // `_this = this; () => class K { [_this.getName()]() { ... } }`
+                    // To make this distinction, use ContainsLexicalThisInComputedPropertyName
+                    // instead of ContainsLexicalThis for computed property names
+                    transformFlags |= 65536 /* ContainsLexicalThisInComputedPropertyName */;
+                }
+                break;
+            case 198 /* SpreadElement */:
+                transformFlags |= 192 /* AssertES2015 */ | 524288 /* ContainsSpread */;
+                break;
+            case 263 /* SpreadAssignment */:
+                transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectSpread */;
+                break;
+            case 97 /* SuperKeyword */:
+                // This node is ES6 syntax.
+                transformFlags |= 192 /* AssertES2015 */;
+                break;
+            case 99 /* ThisKeyword */:
+                // Mark this node and its ancestors as containing a lexical `this` keyword.
+                transformFlags |= 16384 /* ContainsLexicalThis */;
+                break;
+            case 174 /* ObjectBindingPattern */:
+                transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
+                if (subtreeFlags & 524288 /* ContainsRest */) {
+                    transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectRest */;
+                }
+                excludeFlags = 537396545 /* BindingPatternExcludes */;
+                break;
+            case 175 /* ArrayBindingPattern */:
+                transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
+                excludeFlags = 537396545 /* BindingPatternExcludes */;
+                break;
+            case 176 /* BindingElement */:
+                transformFlags |= 192 /* AssertES2015 */;
+                if (node.dotDotDotToken) {
+                    transformFlags |= 524288 /* ContainsRest */;
+                }
+                break;
+            case 147 /* Decorator */:
+                // This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
+                transformFlags |= 3 /* AssertTypeScript */ | 4096 /* ContainsDecorators */;
+                break;
+            case 178 /* ObjectLiteralExpression */:
+                excludeFlags = 540087617 /* ObjectLiteralExcludes */;
+                if (subtreeFlags & 2097152 /* ContainsComputedPropertyName */) {
+                    // If an ObjectLiteralExpression contains a ComputedPropertyName, then it
+                    // is an ES6 node.
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
+                    // A computed property name containing `this` might need to be rewritten,
+                    // so propagate the ContainsLexicalThis flag upward.
+                    transformFlags |= 16384 /* ContainsLexicalThis */;
+                }
+                if (subtreeFlags & 1048576 /* ContainsObjectSpread */) {
+                    // If an ObjectLiteralExpression contains a spread element, then it
+                    // is an ES next node.
+                    transformFlags |= 8 /* AssertESNext */;
+                }
+                break;
+            case 177 /* ArrayLiteralExpression */:
+            case 182 /* NewExpression */:
+                excludeFlags = 537396545 /* ArrayLiteralOrCallOrNewExcludes */;
+                if (subtreeFlags & 524288 /* ContainsSpread */) {
+                    // If the this node contains a SpreadExpression, then it is an ES6
+                    // node.
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                break;
+            case 212 /* DoStatement */:
+            case 213 /* WhileStatement */:
+            case 214 /* ForStatement */:
+            case 215 /* ForInStatement */:
+                // A loop containing a block scoped binding *may* need to be transformed from ES6.
+                if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */) {
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                break;
+            case 265 /* SourceFile */:
+                if (subtreeFlags & 32768 /* ContainsCapturedLexicalThis */) {
+                    transformFlags |= 192 /* AssertES2015 */;
+                }
+                break;
+            case 219 /* ReturnStatement */:
+            case 217 /* ContinueStatement */:
+            case 218 /* BreakStatement */:
+                transformFlags |= 33554432 /* ContainsHoistedDeclarationOrCompletion */;
+                break;
+        }
+        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
+        return transformFlags & ~excludeFlags;
+    }
+    /**
+     * Gets the transform flags to exclude when unioning the transform flags of a subtree.
+     *
+     * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
+     *       For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
+     *       than calling this function.
+     */
+    /* @internal */
+    function getTransformFlagsSubtreeExclusions(kind) {
+        if (kind >= 158 /* FirstTypeNode */ && kind <= 173 /* LastTypeNode */) {
+            return -3 /* TypeExcludes */;
+        }
+        switch (kind) {
+            case 181 /* CallExpression */:
+            case 182 /* NewExpression */:
+            case 177 /* ArrayLiteralExpression */:
+                return 537396545 /* ArrayLiteralOrCallOrNewExcludes */;
+            case 233 /* ModuleDeclaration */:
+                return 574674241 /* ModuleExcludes */;
+            case 146 /* Parameter */:
+                return 536872257 /* ParameterExcludes */;
+            case 187 /* ArrowFunction */:
+                return 601249089 /* ArrowFunctionExcludes */;
+            case 186 /* FunctionExpression */:
+            case 228 /* FunctionDeclaration */:
+                return 601281857 /* FunctionExcludes */;
+            case 227 /* VariableDeclarationList */:
+                return 546309441 /* VariableDeclarationListExcludes */;
+            case 229 /* ClassDeclaration */:
+            case 199 /* ClassExpression */:
+                return 539358529 /* ClassExcludes */;
+            case 152 /* Constructor */:
+                return 601015617 /* ConstructorExcludes */;
+            case 151 /* MethodDeclaration */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+                return 601015617 /* MethodOrAccessorExcludes */;
+            case 119 /* AnyKeyword */:
+            case 133 /* NumberKeyword */:
+            case 130 /* NeverKeyword */:
+            case 136 /* StringKeyword */:
+            case 134 /* ObjectKeyword */:
+            case 122 /* BooleanKeyword */:
+            case 137 /* SymbolKeyword */:
+            case 105 /* VoidKeyword */:
+            case 145 /* TypeParameter */:
+            case 148 /* PropertySignature */:
+            case 150 /* MethodSignature */:
+            case 155 /* CallSignature */:
+            case 156 /* ConstructSignature */:
+            case 157 /* IndexSignature */:
+            case 230 /* InterfaceDeclaration */:
+            case 231 /* TypeAliasDeclaration */:
+                return -3 /* TypeExcludes */;
+            case 178 /* ObjectLiteralExpression */:
+                return 540087617 /* ObjectLiteralExcludes */;
+            case 260 /* CatchClause */:
+                return 537920833 /* CatchClauseExcludes */;
+            case 174 /* ObjectBindingPattern */:
+            case 175 /* ArrayBindingPattern */:
+                return 537396545 /* BindingPatternExcludes */;
+            default:
+                return 536872257 /* NodeExcludes */;
+        }
+    }
+    ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions;
+    /**
+     * "Binds" JSDoc nodes in TypeScript code.
+     * Since we will never create symbols for JSDoc, we just set parent pointers instead.
+     */
+    function setParentPointers(parent, child) {
+        child.parent = parent;
+        ts.forEachChild(child, function (childsChild) { return setParentPointers(child, childsChild); });
+    }
+})(ts || (ts = {}));
+/** @internal */
+var ts;
+(function (ts) {
+    function createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier) {
+        return getSymbolWalker;
+        function getSymbolWalker(accept) {
+            if (accept === void 0) { accept = function () { return true; }; }
+            var visitedTypes = []; // Sparse array from id to type
+            var visitedSymbols = []; // Sparse array from id to symbol
+            return {
+                walkType: function (type) {
+                    try {
+                        visitType(type);
+                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
+                    }
+                    finally {
+                        ts.clear(visitedTypes);
+                        ts.clear(visitedSymbols);
+                    }
+                },
+                walkSymbol: function (symbol) {
+                    try {
+                        visitSymbol(symbol);
+                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
+                    }
+                    finally {
+                        ts.clear(visitedTypes);
+                        ts.clear(visitedSymbols);
+                    }
+                },
+            };
+            function visitType(type) {
+                if (!type) {
+                    return;
+                }
+                if (visitedTypes[type.id]) {
+                    return;
+                }
+                visitedTypes[type.id] = type;
+                // Reuse visitSymbol to visit the type's symbol,
+                //  but be sure to bail on recuring into the type if accept declines the symbol.
+                var shouldBail = visitSymbol(type.symbol);
+                if (shouldBail)
+                    return;
+                // Visit the type's related types, if any
+                if (type.flags & 32768 /* Object */) {
+                    var objectType = type;
+                    var objectFlags = objectType.objectFlags;
+                    if (objectFlags & 4 /* Reference */) {
+                        visitTypeReference(type);
+                    }
+                    if (objectFlags & 32 /* Mapped */) {
+                        visitMappedType(type);
+                    }
+                    if (objectFlags & (1 /* Class */ | 2 /* Interface */)) {
+                        visitInterfaceType(type);
+                    }
+                    if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) {
+                        visitObjectType(objectType);
+                    }
+                }
+                if (type.flags & 16384 /* TypeParameter */) {
+                    visitTypeParameter(type);
+                }
+                if (type.flags & 196608 /* UnionOrIntersection */) {
+                    visitUnionOrIntersectionType(type);
+                }
+                if (type.flags & 262144 /* Index */) {
+                    visitIndexType(type);
+                }
+                if (type.flags & 524288 /* IndexedAccess */) {
+                    visitIndexedAccessType(type);
+                }
+            }
+            function visitTypeReference(type) {
+                visitType(type.target);
+                ts.forEach(type.typeArguments, visitType);
+            }
+            function visitTypeParameter(type) {
+                visitType(getConstraintFromTypeParameter(type));
+            }
+            function visitUnionOrIntersectionType(type) {
+                ts.forEach(type.types, visitType);
+            }
+            function visitIndexType(type) {
+                visitType(type.type);
+            }
+            function visitIndexedAccessType(type) {
+                visitType(type.objectType);
+                visitType(type.indexType);
+                visitType(type.constraint);
+            }
+            function visitMappedType(type) {
+                visitType(type.typeParameter);
+                visitType(type.constraintType);
+                visitType(type.templateType);
+                visitType(type.modifiersType);
+            }
+            function visitSignature(signature) {
+                if (signature.typePredicate) {
+                    visitType(signature.typePredicate.type);
+                }
+                ts.forEach(signature.typeParameters, visitType);
+                for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
+                    var parameter = _a[_i];
+                    visitSymbol(parameter);
+                }
+                visitType(getRestTypeOfSignature(signature));
+                visitType(getReturnTypeOfSignature(signature));
+            }
+            function visitInterfaceType(interfaceT) {
+                visitObjectType(interfaceT);
+                ts.forEach(interfaceT.typeParameters, visitType);
+                ts.forEach(getBaseTypes(interfaceT), visitType);
+                visitType(interfaceT.thisType);
+            }
+            function visitObjectType(type) {
+                var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */);
+                visitType(stringIndexType);
+                var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */);
+                visitType(numberIndexType);
+                // The two checks above *should* have already resolved the type (if needed), so this should be cached
+                var resolved = resolveStructuredTypeMembers(type);
+                for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
+                    var signature = _a[_i];
+                    visitSignature(signature);
+                }
+                for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
+                    var signature = _c[_b];
+                    visitSignature(signature);
+                }
+                for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
+                    var p = _e[_d];
+                    visitSymbol(p);
+                }
+            }
+            function visitSymbol(symbol) {
+                if (!symbol) {
+                    return;
+                }
+                var symbolId = ts.getSymbolId(symbol);
+                if (visitedSymbols[symbolId]) {
+                    return;
+                }
+                visitedSymbols[symbolId] = symbol;
+                if (!accept(symbol)) {
+                    return true;
+                }
+                var t = getTypeOfSymbol(symbol);
+                visitType(t); // Should handle members on classes and such
+                if (symbol.flags & 1952 /* HasExports */) {
+                    symbol.exports.forEach(visitSymbol);
+                }
+                ts.forEach(symbol.declarations, function (d) {
+                    // Type queries are too far resolved when we just visit the symbol's type
+                    //  (their type resolved directly to the member deeply referenced)
+                    // So to get the intervening symbols, we need to check if there's a type
+                    // query node on any of the symbol's declarations and get symbols there
+                    if (d.type && d.type.kind === 162 /* TypeQuery */) {
+                        var query = d.type;
+                        var entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
+                        visitSymbol(entity);
+                    }
+                });
+            }
+        }
+    }
+    ts.createGetSymbolWalker = createGetSymbolWalker;
+})(ts || (ts = {}));
+/// <reference path="core.ts" />
+/// <reference path="diagnosticInformationMap.generated.ts" />
+var ts;
+(function (ts) {
+    function trace(host) {
+        host.trace(ts.formatMessage.apply(undefined, arguments));
+    }
+    ts.trace = trace;
+    /* @internal */
+    function isTraceEnabled(compilerOptions, host) {
+        return compilerOptions.traceResolution && host.trace !== undefined;
+    }
+    ts.isTraceEnabled = isTraceEnabled;
+    function withPackageId(packageId, r) {
+        return r && { path: r.path, extension: r.ext, packageId: packageId };
+    }
+    function noPackageId(r) {
+        return withPackageId(/*packageId*/ undefined, r);
+    }
+    /**
+     * Kinds of file that we are currently looking for.
+     * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
+     */
+    var Extensions;
+    (function (Extensions) {
+        Extensions[Extensions["TypeScript"] = 0] = "TypeScript";
+        Extensions[Extensions["JavaScript"] = 1] = "JavaScript";
+        Extensions[Extensions["DtsOnly"] = 2] = "DtsOnly"; /** Only '.d.ts' */
+    })(Extensions || (Extensions = {}));
+    /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
+    function resolvedTypeScriptOnly(resolved) {
+        if (!resolved) {
+            return undefined;
+        }
+        ts.Debug.assert(ts.extensionIsTypeScript(resolved.extension));
+        return { fileName: resolved.path, packageId: resolved.packageId };
+    }
+    function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) {
+        return {
+            resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId },
+            failedLookupLocations: failedLookupLocations
+        };
+    }
+    /** Reads from "main" or "types"/"typings" depending on `extensions`. */
+    function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) {
+        return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main");
+        function tryReadFromField(fieldName) {
+            if (!ts.hasProperty(jsonContent, fieldName)) {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName);
+                }
+                return;
+            }
+            var fileName = jsonContent[fieldName];
+            if (!ts.isString(fileName)) {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName);
+                }
+                return;
+            }
+            var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName));
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
+            }
+            return path;
+        }
+    }
+    function readJson(path, host) {
+        try {
+            var jsonText = host.readFile(path);
+            return jsonText ? JSON.parse(jsonText) : {};
+        }
+        catch (e) {
+            // gracefully handle if readFile fails or returns not JSON
+            return {};
+        }
+    }
+    function getEffectiveTypeRoots(options, host) {
+        if (options.typeRoots) {
+            return options.typeRoots;
+        }
+        var currentDirectory;
+        if (options.configFilePath) {
+            currentDirectory = ts.getDirectoryPath(options.configFilePath);
+        }
+        else if (host.getCurrentDirectory) {
+            currentDirectory = host.getCurrentDirectory();
+        }
+        if (currentDirectory !== undefined) {
+            return getDefaultTypeRoots(currentDirectory, host);
+        }
+    }
+    ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
+    /**
+     * Returns the path to every node_modules/@types directory from some ancestor directory.
+     * Returns undefined if there are none.
+     */
+    function getDefaultTypeRoots(currentDirectory, host) {
+        if (!host.directoryExists) {
+            return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
+            // And if it doesn't exist, tough.
+        }
+        var typeRoots;
+        ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
+            var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
+            if (host.directoryExists(atTypes)) {
+                (typeRoots || (typeRoots = [])).push(atTypes);
+            }
+            return undefined;
+        });
+        return typeRoots;
+    }
+    var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+    /**
+     * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
+     * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
+     * is assumed to be the same as root directory of the project.
+     */
+    function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host) {
+        var traceEnabled = isTraceEnabled(options, host);
+        var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled };
+        var typeRoots = getEffectiveTypeRoots(options, host);
+        if (traceEnabled) {
+            if (containingFile === undefined) {
+                if (typeRoots === undefined) {
+                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName);
+                }
+                else {
+                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots);
+                }
+            }
+            else {
+                if (typeRoots === undefined) {
+                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile);
+                }
+                else {
+                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
+                }
+            }
+        }
+        var failedLookupLocations = [];
+        var resolved = primaryLookup();
+        var primary = true;
+        if (!resolved) {
+            resolved = secondaryLookup();
+            primary = false;
+        }
+        var resolvedTypeReferenceDirective;
+        if (resolved) {
+            if (!options.preserveSymlinks) {
+                resolved = __assign({}, resolved, { fileName: realPath(resolved.fileName, host, traceEnabled) });
+            }
+            if (traceEnabled) {
+                trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
+            }
+            resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
+        }
+        return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations };
+        function primaryLookup() {
+            // Check primary library paths
+            if (typeRoots && typeRoots.length) {
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
+                }
+                return ts.forEach(typeRoots, function (typeRoot) {
+                    var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
+                    var candidateDirectory = ts.getDirectoryPath(candidate);
+                    var directoryExists = directoryProbablyExists(candidateDirectory, host);
+                    if (!directoryExists && traceEnabled) {
+                        trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
+                    }
+                    return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations, !directoryExists, moduleResolutionState));
+                });
+            }
+            else {
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
+                }
+            }
+        }
+        function secondaryLookup() {
+            var resolvedFile;
+            var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile);
+            if (initialLocationForSecondaryLookup !== undefined) {
+                // check secondary locations
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
+                }
+                var result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined);
+                resolvedFile = resolvedTypeScriptOnly(result && result.value);
+                if (!resolvedFile && traceEnabled) {
+                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
+                }
+                return resolvedFile;
+            }
+            else {
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
+                }
+            }
+        }
+    }
+    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
+    /**
+     * Given a set of options, returns the set of type directive names
+     *   that should be included for this program automatically.
+     * This list could either come from the config file,
+     *   or from enumerating the types root + initial secondary types lookup location.
+     * More type directives might appear in the program later as a result of loading actual source files;
+     *   this list is only the set of defaults that are implicitly included.
+     */
+    function getAutomaticTypeDirectiveNames(options, host) {
+        // Use explicit type list from tsconfig.json
+        if (options.types) {
+            return options.types;
+        }
+        // Walk the primary type lookup locations
+        var result = [];
+        if (host.directoryExists && host.getDirectories) {
+            var typeRoots = getEffectiveTypeRoots(options, host);
+            if (typeRoots) {
+                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
+                    var root = typeRoots_1[_i];
+                    if (host.directoryExists(root)) {
+                        for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) {
+                            var typeDirectivePath = _b[_a];
+                            var normalized = ts.normalizePath(typeDirectivePath);
+                            var packageJsonPath = pathToPackageJson(ts.combinePaths(root, normalized));
+                            // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
+                            // See `createNotNeededPackageJSON` in the types-publisher` repo.
+                            // tslint:disable-next-line:no-null-keyword
+                            var isNotNeededPackage = host.fileExists(packageJsonPath) && readJson(packageJsonPath, host).typings === null;
+                            if (!isNotNeededPackage) {
+                                // Return just the type directive names
+                                result.push(ts.getBaseFileName(normalized));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
+    function createModuleResolutionCache(currentDirectory, getCanonicalFileName) {
+        var directoryToModuleNameMap = ts.createMap();
+        var moduleNameToDirectoryMap = ts.createMap();
+        return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName };
+        function getOrCreateCacheForDirectory(directoryName) {
+            var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName);
+            var perFolderCache = directoryToModuleNameMap.get(path);
+            if (!perFolderCache) {
+                perFolderCache = ts.createMap();
+                directoryToModuleNameMap.set(path, perFolderCache);
+            }
+            return perFolderCache;
+        }
+        function getOrCreateCacheForModuleName(nonRelativeModuleName) {
+            if (ts.isExternalModuleNameRelative(nonRelativeModuleName)) {
+                return undefined;
+            }
+            var perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
+            if (!perModuleNameCache) {
+                perModuleNameCache = createPerModuleNameCache();
+                moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache);
+            }
+            return perModuleNameCache;
+        }
+        function createPerModuleNameCache() {
+            var directoryPathMap = ts.createMap();
+            return { get: get, set: set };
+            function get(directory) {
+                return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName));
+            }
+            /**
+             * At first this function add entry directory -> module resolution result to the table.
+             * Then it computes the set of parent folders for 'directory' that should have the same module resolution result
+             * and for every parent folder in set it adds entry: parent -> module resolution. .
+             * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
+             * Set of parent folders that should have the same result will be:
+             * [
+             *     /a/b/c/d, /a/b/c, /a/b
+             * ]
+             * this means that request for module resolution from file in any of these folder will be immediately found in cache.
+             */
+            function set(directory, result) {
+                var path = ts.toPath(directory, currentDirectory, getCanonicalFileName);
+                // if entry is already in cache do nothing
+                if (directoryPathMap.has(path)) {
+                    return;
+                }
+                directoryPathMap.set(path, result);
+                var resolvedFileName = result.resolvedModule && result.resolvedModule.resolvedFileName;
+                // find common prefix between directory and resolved file name
+                // this common prefix should be the shorted path that has the same resolution
+                // directory: /a/b/c/d/e
+                // resolvedFileName: /a/b/foo.d.ts
+                var commonPrefix = getCommonPrefix(path, resolvedFileName);
+                var current = path;
+                while (true) {
+                    var parent = ts.getDirectoryPath(current);
+                    if (parent === current || directoryPathMap.has(parent)) {
+                        break;
+                    }
+                    directoryPathMap.set(parent, result);
+                    current = parent;
+                    if (current === commonPrefix) {
+                        break;
+                    }
+                }
+            }
+            function getCommonPrefix(directory, resolution) {
+                if (resolution === undefined) {
+                    return undefined;
+                }
+                var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
+                // find first position where directory and resolution differs
+                var i = 0;
+                while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
+                    i++;
+                }
+                // find last directory separator before position i
+                var sep = directory.lastIndexOf(ts.directorySeparator, i);
+                if (sep < 0) {
+                    return undefined;
+                }
+                return directory.substr(0, sep);
+            }
+        }
+    }
+    ts.createModuleResolutionCache = createModuleResolutionCache;
+    function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache) {
+        var traceEnabled = isTraceEnabled(compilerOptions, host);
+        if (traceEnabled) {
+            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
+        }
+        var containingDirectory = ts.getDirectoryPath(containingFile);
+        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
+        var result = perFolderCache && perFolderCache.get(moduleName);
+        if (result) {
+            if (traceEnabled) {
+                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
+            }
+        }
+        else {
+            var moduleResolution = compilerOptions.moduleResolution;
+            if (moduleResolution === undefined) {
+                moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]);
+                }
+            }
+            else {
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]);
+                }
+            }
+            switch (moduleResolution) {
+                case ts.ModuleResolutionKind.NodeJs:
+                    result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache);
+                    break;
+                case ts.ModuleResolutionKind.Classic:
+                    result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
+                    break;
+                default:
+                    ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution);
+            }
+            if (perFolderCache) {
+                perFolderCache.set(moduleName, result);
+                // put result in per-module name cache
+                var perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName);
+                if (perModuleNameCache) {
+                    perModuleNameCache.set(containingDirectory, result);
+                }
+            }
+        }
+        if (traceEnabled) {
+            if (result.resolvedModule) {
+                trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
+            }
+            else {
+                trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName);
+            }
+        }
+        return result;
+    }
+    ts.resolveModuleName = resolveModuleName;
+    /**
+     * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
+     * mitigate differences between design time structure of the project and its runtime counterpart so the same import name
+     * can be resolved successfully by TypeScript compiler and runtime module loader.
+     * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will
+     * fallback to standard resolution routine.
+     *
+     * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative
+     * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will
+     * be '/a/b/c/d'
+     * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names
+     * will be resolved based on the content of the module name.
+     * Structure of 'paths' compiler options
+     * 'paths': {
+     *    pattern-1: [...substitutions],
+     *    pattern-2: [...substitutions],
+     *    ...
+     *    pattern-n: [...substitutions]
+     * }
+     * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against
+     * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case.
+     * If pattern contains '*' then to match pattern "<prefix>*<suffix>" module name must start with the <prefix> and end with <suffix>.
+     * <MatchedStar> denotes part of the module name between <prefix> and <suffix>.
+     * If module name can be matches with multiple patterns then pattern with the longest prefix will be picked.
+     * After selecting pattern we'll use list of substitutions to get candidate locations of the module and the try to load module
+     * from the candidate location.
+     * Substitution is a string that can contain zero or one '*'. To get candidate location from substitution we'll pick every
+     * substitution in the list and replace '*' with <MatchedStar> string. If candidate location is not rooted it
+     * will be converted to absolute using baseUrl.
+     * For example:
+     * baseUrl: /a/b/c
+     * "paths": {
+     *     // match all module names
+     *     "*": [
+     *         "*",        // use matched name as is,
+     *                     // <matched name> will be looked as /a/b/c/<matched name>
+     *
+     *         "folder1/*" // substitution will convert matched name to 'folder1/<matched name>',
+     *                     // since it is not rooted then final candidate location will be /a/b/c/folder1/<matched name>
+     *     ],
+     *     // match module names that start with 'components/'
+     *     "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/<matched name> to '/root/components/folder1/<matched name>',
+     *                                              // it is rooted so it will be final candidate location
+     * }
+     *
+     * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if
+     * they were in the same location. For example lets say there are two files
+     * '/local/src/content/file1.ts'
+     * '/shared/components/contracts/src/content/protocols/file2.ts'
+     * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so
+     * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime.
+     * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all
+     * root dirs were merged together.
+     * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ].
+     * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file:
+     * '/local/src/content/protocols/file2' and try to load it - failure.
+     * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will
+     * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
+     * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
+     */
+    function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) {
+        if (!ts.isExternalModuleNameRelative(moduleName)) {
+            return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
+        }
+        else {
+            return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
+        }
+    }
+    function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) {
+        if (!state.compilerOptions.rootDirs) {
+            return undefined;
+        }
+        if (state.traceEnabled) {
+            trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName);
+        }
+        var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
+        var matchedRootDir;
+        var matchedNormalizedPrefix;
+        for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) {
+            var rootDir = _a[_i];
+            // rootDirs are expected to be absolute
+            // in case of tsconfig.json this will happen automatically - compiler will expand relative names
+            // using location of tsconfig.json as base location
+            var normalizedRoot = ts.normalizePath(rootDir);
+            if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) {
+                normalizedRoot += ts.directorySeparator;
+            }
+            var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) &&
+                (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length);
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix);
+            }
+            if (isLongestMatchingPrefix) {
+                matchedNormalizedPrefix = normalizedRoot;
+                matchedRootDir = rootDir;
+            }
+        }
+        if (matchedNormalizedPrefix) {
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix);
+            }
+            var suffix = candidate.substr(matchedNormalizedPrefix.length);
+            // first - try to load from a initial location
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
+            }
+            var resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
+            if (resolvedFileName) {
+                return resolvedFileName;
+            }
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs);
+            }
+            // then try to resolve using remaining entries in rootDirs
+            for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) {
+                var rootDir = _c[_b];
+                if (rootDir === matchedRootDir) {
+                    // skip the initially matched entry
+                    continue;
+                }
+                var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix);
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1);
+                }
+                var baseDirectory = ts.getDirectoryPath(candidate_1);
+                var resolvedFileName_1 = loader(extensions, candidate_1, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
+                if (resolvedFileName_1) {
+                    return resolvedFileName_1;
+                }
+            }
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed);
+            }
+        }
+        return undefined;
+    }
+    function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state) {
+        if (!state.compilerOptions.baseUrl) {
+            return undefined;
+        }
+        if (state.traceEnabled) {
+            trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, state.compilerOptions.baseUrl, moduleName);
+        }
+        // string is for exact match
+        var matchedPattern = undefined;
+        if (state.compilerOptions.paths) {
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
+            }
+            matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(state.compilerOptions.paths), moduleName);
+        }
+        if (matchedPattern) {
+            var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName);
+            var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern);
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
+            }
+            return ts.forEach(state.compilerOptions.paths[matchedPatternText], function (subst) {
+                var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst;
+                var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, path));
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
+                }
+                // A path mapping may have an extension, in contrast to an import, which should omit it.
+                var extension = ts.tryGetExtensionFromPath(candidate);
+                if (extension !== undefined) {
+                    var path_1 = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
+                    if (path_1 !== undefined) {
+                        return noPackageId({ path: path_1, ext: extension });
+                    }
+                }
+                return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
+            });
+        }
+        else {
+            var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, moduleName));
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
+            }
+            return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
+        }
+    }
+    function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) {
+        return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
+    }
+    ts.nodeModuleNameResolver = nodeModuleNameResolver;
+    /**
+     * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
+     * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
+     * Throws an error if the module can't be resolved.
+     */
+    /* @internal */
+    function resolveJavaScriptModule(moduleName, initialDir, host) {
+        var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
+        if (!resolvedModule) {
+            throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", "));
+        }
+        return resolvedModule.resolvedFileName;
+    }
+    ts.resolveJavaScriptModule = resolveJavaScriptModule;
+    function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, jsOnly) {
+        var traceEnabled = isTraceEnabled(compilerOptions, host);
+        var failedLookupLocations = [];
+        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
+        var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
+        if (result && result.value) {
+            var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport;
+            return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
+        }
+        return { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
+        function tryResolve(extensions) {
+            var loader = function (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true); };
+            var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
+            if (resolved) {
+                return toSearchResult({ resolved: resolved, isExternalLibraryImport: false });
+            }
+            if (!ts.isExternalModuleNameRelative(moduleName)) {
+                if (traceEnabled) {
+                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
+                }
+                var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache);
+                if (!resolved_1)
+                    return undefined;
+                var resolvedValue = resolved_1.value;
+                if (!compilerOptions.preserveSymlinks) {
+                    resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realPath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension });
+                }
+                // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
+                return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
+            }
+            else {
+                var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts;
+                var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
+                // Treat explicit "node_modules" import as an external library import.
+                return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") });
+            }
+        }
+    }
+    function realPath(path, host, traceEnabled) {
+        if (!host.realpath) {
+            return path;
+        }
+        var real = ts.normalizePath(host.realpath(path));
+        if (traceEnabled) {
+            trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real);
+        }
+        return real;
+    }
+    function nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) {
+        if (state.traceEnabled) {
+            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
+        }
+        if (!ts.pathEndsWithDirectorySeparator(candidate)) {
+            if (!onlyRecordFailures) {
+                var parentOfCandidate = ts.getDirectoryPath(candidate);
+                if (!directoryProbablyExists(parentOfCandidate, state.host)) {
+                    if (state.traceEnabled) {
+                        trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate);
+                    }
+                    onlyRecordFailures = true;
+                }
+            }
+            var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
+            if (resolvedFromFile) {
+                return noPackageId(resolvedFromFile);
+            }
+        }
+        if (!onlyRecordFailures) {
+            var candidateExists = directoryProbablyExists(candidate, state.host);
+            if (!candidateExists) {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
+                }
+                onlyRecordFailures = true;
+            }
+        }
+        return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson);
+    }
+    /* @internal */
+    function directoryProbablyExists(directoryName, host) {
+        // if host does not support 'directoryExists' assume that directory will exist
+        return !host.directoryExists || host.directoryExists(directoryName);
+    }
+    ts.directoryProbablyExists = directoryProbablyExists;
+    function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) {
+        return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state));
+    }
+    /**
+     * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
+     * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
+     */
+    function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) {
+        // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
+        var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
+        if (resolvedByAddingExtension) {
+            return resolvedByAddingExtension;
+        }
+        // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
+        // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
+        if (ts.hasJavaScriptFileExtension(candidate)) {
+            var extensionless = ts.removeFileExtension(candidate);
+            if (state.traceEnabled) {
+                var extension = candidate.substring(extensionless.length);
+                trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
+            }
+            return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
+        }
+    }
+    /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
+    function tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state) {
+        if (!onlyRecordFailures) {
+            // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
+            var directory = ts.getDirectoryPath(candidate);
+            if (directory) {
+                onlyRecordFailures = !directoryProbablyExists(directory, state.host);
+            }
+        }
+        switch (extensions) {
+            case Extensions.DtsOnly:
+                return tryExtension(".d.ts" /* Dts */);
+            case Extensions.TypeScript:
+                return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */);
+            case Extensions.JavaScript:
+                return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */);
+        }
+        function tryExtension(ext) {
+            var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
+            return path && { path: path, ext: ext };
+        }
+    }
+    /** Return the file if it exists. */
+    function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) {
+        if (!onlyRecordFailures) {
+            if (state.host.fileExists(fileName)) {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
+                }
+                return fileName;
+            }
+            else {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName);
+                }
+            }
+        }
+        failedLookupLocations.push(fileName);
+        return undefined;
+    }
+    function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) {
+        if (considerPackageJson === void 0) { considerPackageJson = true; }
+        var _a = considerPackageJson
+            ? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state)
+            : { packageJsonContent: undefined, packageId: undefined }, packageJsonContent = _a.packageJsonContent, packageId = _a.packageId;
+        return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent));
+    }
+    function loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent) {
+        var fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state);
+        if (fromPackageJson) {
+            return fromPackageJson;
+        }
+        var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
+        return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
+    }
+    function getPackageJsonInfo(nodeModuleDirectory, subModuleName, failedLookupLocations, onlyRecordFailures, _a) {
+        var host = _a.host, traceEnabled = _a.traceEnabled;
+        var directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host);
+        var packageJsonPath = pathToPackageJson(nodeModuleDirectory);
+        if (directoryExists && host.fileExists(packageJsonPath)) {
+            if (traceEnabled) {
+                trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
+            }
+            var packageJsonContent = readJson(packageJsonPath, host);
+            var packageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
+                ? { name: packageJsonContent.name, subModuleName: subModuleName, version: packageJsonContent.version }
+                : undefined;
+            return { found: true, packageJsonContent: packageJsonContent, packageId: packageId };
+        }
+        else {
+            if (directoryExists && traceEnabled) {
+                trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath);
+            }
+            // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
+            failedLookupLocations.push(packageJsonPath);
+            return { found: false, packageJsonContent: undefined, packageId: undefined };
+        }
+    }
+    function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) {
+        var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state);
+        if (!file) {
+            return undefined;
+        }
+        var onlyRecordFailures = !directoryProbablyExists(ts.getDirectoryPath(file), state.host);
+        var fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state);
+        if (fromFile) {
+            var resolved = fromFile && resolvedIfExtensionMatches(extensions, fromFile);
+            if (resolved) {
+                return resolved;
+            }
+            if (state.traceEnabled) {
+                trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
+            }
+        }
+        // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
+        var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
+        // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
+        var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false);
+        if (result) {
+            // It won't have a `packageId` set, because we disabled `considerPackageJson`.
+            ts.Debug.assert(result.packageId === undefined);
+            return { path: result.path, ext: result.extension };
+        }
+    }
+    /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
+    function resolvedIfExtensionMatches(extensions, path) {
+        var ext = ts.tryGetExtensionFromPath(path);
+        return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined;
+    }
+    /** True if `extension` is one of the supported `extensions`. */
+    function extensionIsOk(extensions, extension) {
+        switch (extensions) {
+            case Extensions.JavaScript:
+                return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */;
+            case Extensions.TypeScript:
+                return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */;
+            case Extensions.DtsOnly:
+                return extension === ".d.ts" /* Dts */;
+        }
+    }
+    function pathToPackageJson(directory) {
+        return ts.combinePaths(directory, "package.json");
+    }
+    function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) {
+        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
+        // First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
+        var packageJsonContent;
+        var packageId;
+        var packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state);
+        if (packageInfo.found) {
+            (packageJsonContent = packageInfo.packageJsonContent, packageId = packageInfo.packageId);
+        }
+        else {
+            var _a = getPackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+            if (rest !== "") {
+                var packageRootPath = ts.combinePaths(nodeModulesFolder, packageName);
+                // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId.
+                packageId = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state).packageId;
+            }
+        }
+        var pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
+            loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
+        return withPackageId(packageId, pathAndExtension);
+    }
+    /* @internal */
+    function getPackageName(moduleName) {
+        var idx = moduleName.indexOf(ts.directorySeparator);
+        if (moduleName[0] === "@") {
+            idx = moduleName.indexOf(ts.directorySeparator, idx + 1);
+        }
+        return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
+    }
+    ts.getPackageName = getPackageName;
+    function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) {
+        return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache);
+    }
+    function loadModuleFromNodeModulesAtTypes(moduleName, directory, failedLookupLocations, state) {
+        // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
+        return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined);
+    }
+    function loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, typesOnly, cache) {
+        var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
+        return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) {
+            if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") {
+                var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host);
+                if (resolutionFromCache) {
+                    return resolutionFromCache;
+                }
+                return toSearchResult(loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly));
+            }
+        });
+    }
+    /** Load a module from a single node_modules directory, but not from any ancestors' node_modules directories. */
+    function loadModuleFromNodeModulesOneLevel(extensions, moduleName, directory, failedLookupLocations, state, typesOnly) {
+        if (typesOnly === void 0) { typesOnly = false; }
+        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
+        var nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
+        if (!nodeModulesFolderExists && state.traceEnabled) {
+            trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
+        }
+        var packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state);
+        if (packageResult) {
+            return packageResult;
+        }
+        if (extensions !== Extensions.JavaScript) {
+            var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types");
+            var nodeModulesAtTypesExists = nodeModulesFolderExists;
+            if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes_1, state.host)) {
+                if (state.traceEnabled) {
+                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1);
+                }
+                nodeModulesAtTypesExists = false;
+            }
+            return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, failedLookupLocations, state);
+        }
+    }
+    /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
+    var mangledScopedPackageSeparator = "__";
+    /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
+    function mangleScopedPackage(packageName, state) {
+        var mangled = getMangledNameForScopedPackage(packageName);
+        if (state.traceEnabled && mangled !== packageName) {
+            trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled);
+        }
+        return mangled;
+    }
+    /* @internal */
+    function getTypesPackageName(packageName) {
+        return "@types/" + getMangledNameForScopedPackage(packageName);
+    }
+    ts.getTypesPackageName = getTypesPackageName;
+    function getMangledNameForScopedPackage(packageName) {
+        if (ts.startsWith(packageName, "@")) {
+            var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
+            if (replaceSlash !== packageName) {
+                return replaceSlash.slice(1); // Take off the "@"
+            }
+        }
+        return packageName;
+    }
+    /* @internal */
+    function getPackageNameFromAtTypesDirectory(mangledName) {
+        var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/");
+        if (withoutAtTypePrefix !== mangledName) {
+            return ts.stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ?
+                "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
+                withoutAtTypePrefix;
+        }
+        return mangledName;
+    }
+    ts.getPackageNameFromAtTypesDirectory = getPackageNameFromAtTypesDirectory;
+    function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, traceEnabled, host) {
+        var result = cache && cache.get(containingDirectory);
+        if (result) {
+            if (traceEnabled) {
+                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
+            }
+            return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
+        }
+    }
+    function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) {
+        var traceEnabled = isTraceEnabled(compilerOptions, host);
+        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
+        var failedLookupLocations = [];
+        var containingDirectory = ts.getDirectoryPath(containingFile);
+        var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
+        return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
+        function tryResolve(extensions) {
+            var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
+            if (resolvedUsingSettings) {
+                return { value: resolvedUsingSettings };
+            }
+            var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
+            if (!ts.isExternalModuleNameRelative(moduleName)) {
+                // Climb up parent directories looking for a module.
+                var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) {
+                    var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host);
+                    if (resolutionFromCache) {
+                        return resolutionFromCache;
+                    }
+                    var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName));
+                    return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state));
+                });
+                if (resolved_3) {
+                    return resolved_3;
+                }
+                if (extensions === Extensions.TypeScript) {
+                    // If we didn't find the file normally, look it up in @types.
+                    return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
+                }
+            }
+            else {
+                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
+                return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state));
+            }
+        }
+    }
+    ts.classicNameResolver = classicNameResolver;
+    /**
+     * LSHost may load a module from a global cache of typings.
+     * This is the minumum code needed to expose that functionality; the rest is in LSHost.
+     */
+    /* @internal */
+    function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) {
+        var traceEnabled = isTraceEnabled(compilerOptions, host);
+        if (traceEnabled) {
+            trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
+        }
+        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
+        var failedLookupLocations = [];
+        var resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
+        return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
+    }
+    ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache;
+    /**
+     * Wraps value to SearchResult.
+     * @returns undefined if value is undefined or { value } otherwise
+     */
+    function toSearchResult(value) {
+        return value !== undefined ? { value: value } : undefined;
+    }
+})(ts || (ts = {}));
+/// <reference path="moduleNameResolver.ts"/>
+/// <reference path="binder.ts"/>
+/// <reference path="symbolWalker.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    var ambientModuleSymbolRegex = /^".+"$/;
+    var nextSymbolId = 1;
+    var nextNodeId = 1;
+    var nextMergeId = 1;
+    var nextFlowId = 1;
+    function getNodeId(node) {
+        if (!node.id) {
+            node.id = nextNodeId;
+            nextNodeId++;
+        }
+        return node.id;
+    }
+    ts.getNodeId = getNodeId;
+    function getSymbolId(symbol) {
+        if (!symbol.id) {
+            symbol.id = nextSymbolId;
+            nextSymbolId++;
+        }
+        return symbol.id;
+    }
+    ts.getSymbolId = getSymbolId;
+    function isInstantiatedModule(node, preserveConstEnums) {
+        var moduleState = ts.getModuleInstanceState(node);
+        return moduleState === 1 /* Instantiated */ ||
+            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
+    }
+    ts.isInstantiatedModule = isInstantiatedModule;
+    function createTypeChecker(host, produceDiagnostics) {
+        // Cancellation that controls whether or not we can cancel in the middle of type checking.
+        // In general cancelling is *not* safe for the type checker.  We might be in the middle of
+        // computing something, and we will leave our internals in an inconsistent state.  Callers
+        // who set the cancellation token should catch if a cancellation exception occurs, and
+        // should throw away and create a new TypeChecker.
+        //
+        // Currently we only support setting the cancellation token when getting diagnostics.  This
+        // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
+        // they no longer need the information (for example, if the user started editing again).
+        var cancellationToken;
+        var requestedExternalEmitHelpers;
+        var externalHelpersModule;
+        var Symbol = ts.objectAllocator.getSymbolConstructor();
+        var Type = ts.objectAllocator.getTypeConstructor();
+        var Signature = ts.objectAllocator.getSignatureConstructor();
+        var typeCount = 0;
+        var symbolCount = 0;
+        var enumCount = 0;
+        var symbolInstantiationDepth = 0;
+        var emptySymbols = ts.createSymbolTable();
+        var identityMapper = ts.identity;
+        var compilerOptions = host.getCompilerOptions();
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var modulekind = ts.getEmitModuleKind(compilerOptions);
+        var noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters;
+        var allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ts.ModuleKind.System;
+        var strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks;
+        var strictFunctionTypes = compilerOptions.strictFunctionTypes === undefined ? compilerOptions.strict : compilerOptions.strictFunctionTypes;
+        var noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny;
+        var noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis;
+        var emitResolver = createResolver();
+        var nodeBuilder = createNodeBuilder();
+        var undefinedSymbol = createSymbol(4 /* Property */, "undefined");
+        undefinedSymbol.declarations = [];
+        var argumentsSymbol = createSymbol(4 /* Property */, "arguments");
+        /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
+        var apparentArgumentCount;
+        // for public members that accept a Node or one of its subtypes, we must guard against
+        // synthetic nodes created during transformations by calling `getParseTreeNode`.
+        // for most of these, we perform the guard only on `checker` to avoid any possible
+        // extra cost of calling `getParseTreeNode` when calling these functions from inside the
+        // checker.
+        var checker = {
+            getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); },
+            getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); },
+            getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; },
+            getTypeCount: function () { return typeCount; },
+            isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
+            isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
+            isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; },
+            getMergedSymbol: getMergedSymbol,
+            getDiagnostics: getDiagnostics,
+            getGlobalDiagnostics: getGlobalDiagnostics,
+            getTypeOfSymbolAtLocation: function (symbol, location) {
+                location = ts.getParseTreeNode(location);
+                return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType;
+            },
+            getSymbolsOfParameterPropertyDeclaration: function (parameter, parameterName) {
+                parameter = ts.getParseTreeNode(parameter, ts.isParameter);
+                ts.Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
+                return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName));
+            },
+            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
+            getPropertiesOfType: getPropertiesOfType,
+            getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
+            getIndexInfoOfType: getIndexInfoOfType,
+            getSignaturesOfType: getSignaturesOfType,
+            getIndexTypeOfType: getIndexTypeOfType,
+            getBaseTypes: getBaseTypes,
+            getBaseTypeOfLiteralType: getBaseTypeOfLiteralType,
+            getWidenedType: getWidenedType,
+            getTypeFromTypeNode: function (node) {
+                node = ts.getParseTreeNode(node, ts.isTypeNode);
+                return node ? getTypeFromTypeNode(node) : unknownType;
+            },
+            getParameterType: getTypeAtPosition,
+            getReturnTypeOfSignature: getReturnTypeOfSignature,
+            getNullableType: getNullableType,
+            getNonNullableType: getNonNullableType,
+            typeToTypeNode: nodeBuilder.typeToTypeNode,
+            indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
+            signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration,
+            getSymbolsInScope: function (location, meaning) {
+                location = ts.getParseTreeNode(location);
+                return location ? getSymbolsInScope(location, meaning) : [];
+            },
+            getSymbolAtLocation: function (node) {
+                node = ts.getParseTreeNode(node);
+                return node ? getSymbolAtLocation(node) : undefined;
+            },
+            getShorthandAssignmentValueSymbol: function (node) {
+                node = ts.getParseTreeNode(node);
+                return node ? getShorthandAssignmentValueSymbol(node) : undefined;
+            },
+            getExportSpecifierLocalTargetSymbol: function (node) {
+                node = ts.getParseTreeNode(node, ts.isExportSpecifier);
+                return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
+            },
+            getExportSymbolOfSymbol: function (symbol) {
+                return getMergedSymbol(symbol.exportSymbol || symbol);
+            },
+            getTypeAtLocation: function (node) {
+                node = ts.getParseTreeNode(node);
+                return node ? getTypeOfNode(node) : unknownType;
+            },
+            getPropertySymbolOfDestructuringAssignment: function (location) {
+                location = ts.getParseTreeNode(location, ts.isIdentifier);
+                return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
+            },
+            signatureToString: function (signature, enclosingDeclaration, flags, kind) {
+                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind);
+            },
+            typeToString: function (type, enclosingDeclaration, flags) {
+                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags);
+            },
+            getSymbolDisplayBuilder: getSymbolDisplayBuilder,
+            symbolToString: function (symbol, enclosingDeclaration, meaning) {
+                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning);
+            },
+            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
+            getRootSymbols: getRootSymbols,
+            getContextualType: function (node) {
+                node = ts.getParseTreeNode(node, ts.isExpression);
+                return node ? getContextualType(node) : undefined;
+            },
+            getFullyQualifiedName: getFullyQualifiedName,
+            getResolvedSignature: function (node, candidatesOutArray, theArgumentCount) {
+                node = ts.getParseTreeNode(node, ts.isCallLikeExpression);
+                apparentArgumentCount = theArgumentCount;
+                var res = node ? getResolvedSignature(node, candidatesOutArray) : undefined;
+                apparentArgumentCount = undefined;
+                return res;
+            },
+            getConstantValue: function (node) {
+                node = ts.getParseTreeNode(node, canHaveConstantValue);
+                return node ? getConstantValue(node) : undefined;
+            },
+            isValidPropertyAccess: function (node, propertyName) {
+                node = ts.getParseTreeNode(node, ts.isPropertyAccessOrQualifiedName);
+                return node ? isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName)) : false;
+            },
+            getSignatureFromDeclaration: function (declaration) {
+                declaration = ts.getParseTreeNode(declaration, ts.isFunctionLike);
+                return declaration ? getSignatureFromDeclaration(declaration) : undefined;
+            },
+            isImplementationOfOverload: function (node) {
+                var parsed = ts.getParseTreeNode(node, ts.isFunctionLike);
+                return parsed ? isImplementationOfOverload(parsed) : undefined;
+            },
+            getImmediateAliasedSymbol: function (symbol) {
+                ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
+                var links = getSymbolLinks(symbol);
+                if (!links.immediateTarget) {
+                    var node = getDeclarationOfAliasSymbol(symbol);
+                    ts.Debug.assert(!!node);
+                    links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
+                }
+                return links.immediateTarget;
+            },
+            getAliasedSymbol: resolveAlias,
+            getEmitResolver: getEmitResolver,
+            getExportsOfModule: getExportsOfModuleAsArray,
+            getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule,
+            getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier),
+            getAmbientModules: getAmbientModules,
+            getAllAttributesTypeFromJsxOpeningLikeElement: function (node) {
+                node = ts.getParseTreeNode(node, ts.isJsxOpeningLikeElement);
+                return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined;
+            },
+            getJsxIntrinsicTagNames: getJsxIntrinsicTagNames,
+            isOptionalParameter: function (node) {
+                node = ts.getParseTreeNode(node, ts.isParameter);
+                return node ? isOptionalParameter(node) : false;
+            },
+            tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); },
+            tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); },
+            tryFindAmbientModuleWithoutAugmentations: function (moduleName) {
+                // we deliberately exclude augmentations
+                // since we are only interested in declarations of the module itself
+                return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
+            },
+            getApparentType: getApparentType,
+            getUnionType: getUnionType,
+            createAnonymousType: createAnonymousType,
+            createSignature: createSignature,
+            createSymbol: createSymbol,
+            createIndexInfo: createIndexInfo,
+            getAnyType: function () { return anyType; },
+            getStringType: function () { return stringType; },
+            getNumberType: function () { return numberType; },
+            createPromiseType: createPromiseType,
+            createArrayType: createArrayType,
+            getBooleanType: function () { return booleanType; },
+            getVoidType: function () { return voidType; },
+            getUndefinedType: function () { return undefinedType; },
+            getNullType: function () { return nullType; },
+            getESSymbolType: function () { return esSymbolType; },
+            getNeverType: function () { return neverType; },
+            isSymbolAccessible: isSymbolAccessible,
+            isArrayLikeType: isArrayLikeType,
+            getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes,
+            getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); },
+            getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
+            getBaseConstraintOfType: getBaseConstraintOfType,
+            resolveName: function (name, location, meaning) {
+                return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
+            },
+            getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); },
+        };
+        var tupleTypes = [];
+        var unionTypes = ts.createMap();
+        var intersectionTypes = ts.createMap();
+        var literalTypes = ts.createMap();
+        var indexedAccessTypes = ts.createMap();
+        var evolvingArrayTypes = [];
+        var unknownSymbol = createSymbol(4 /* Property */, "unknown");
+        var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */);
+        var anyType = createIntrinsicType(1 /* Any */, "any");
+        var autoType = createIntrinsicType(1 /* Any */, "any");
+        var unknownType = createIntrinsicType(1 /* Any */, "unknown");
+        var undefinedType = createIntrinsicType(2048 /* Undefined */, "undefined");
+        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(2048 /* Undefined */ | 2097152 /* ContainsWideningType */, "undefined");
+        var nullType = createIntrinsicType(4096 /* Null */, "null");
+        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(4096 /* Null */ | 2097152 /* ContainsWideningType */, "null");
+        var stringType = createIntrinsicType(2 /* String */, "string");
+        var numberType = createIntrinsicType(4 /* Number */, "number");
+        var trueType = createIntrinsicType(128 /* BooleanLiteral */, "true");
+        var falseType = createIntrinsicType(128 /* BooleanLiteral */, "false");
+        var booleanType = createBooleanType([trueType, falseType]);
+        var esSymbolType = createIntrinsicType(512 /* ESSymbol */, "symbol");
+        var voidType = createIntrinsicType(1024 /* Void */, "void");
+        var neverType = createIntrinsicType(8192 /* Never */, "never");
+        var silentNeverType = createIntrinsicType(8192 /* Never */, "never");
+        var nonPrimitiveType = createIntrinsicType(16777216 /* NonPrimitive */, "object");
+        var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
+        emptyTypeLiteralSymbol.members = ts.createSymbolTable();
+        var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        emptyGenericType.instantiations = ts.createMap();
+        var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
+        // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
+        anyFunctionType.flags |= 8388608 /* ContainsAnyFunctionType */;
+        var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+        var markerSuperType = createType(16384 /* TypeParameter */);
+        var markerSubType = createType(16384 /* TypeParameter */);
+        markerSubType.constraint = markerSuperType;
+        var markerOtherType = createType(16384 /* TypeParameter */);
+        var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
+        var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
+        var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
+        var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
+        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
+        var jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
+        var globals = ts.createSymbolTable();
+        var ambientModulesCache;
+        /**
+         * List of every ambient module with a "*" wildcard.
+         * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
+         * This is only used if there is no exact match.
+         */
+        var patternAmbientModules;
+        var globalObjectType;
+        var globalFunctionType;
+        var globalArrayType;
+        var globalReadonlyArrayType;
+        var globalStringType;
+        var globalNumberType;
+        var globalBooleanType;
+        var globalRegExpType;
+        var globalThisType;
+        var anyArrayType;
+        var autoArrayType;
+        var anyReadonlyArrayType;
+        // The library files are only loaded when the feature is used.
+        // This allows users to just specify library files they want to used through --lib
+        // and they will not get an error from not having unrelated library files
+        var deferredGlobalESSymbolConstructorSymbol;
+        var deferredGlobalESSymbolType;
+        var deferredGlobalTypedPropertyDescriptorType;
+        var deferredGlobalPromiseType;
+        var deferredGlobalPromiseConstructorSymbol;
+        var deferredGlobalPromiseConstructorLikeType;
+        var deferredGlobalIterableType;
+        var deferredGlobalIteratorType;
+        var deferredGlobalIterableIteratorType;
+        var deferredGlobalAsyncIterableType;
+        var deferredGlobalAsyncIteratorType;
+        var deferredGlobalAsyncIterableIteratorType;
+        var deferredGlobalTemplateStringsArrayType;
+        var deferredJsxElementClassType;
+        var deferredJsxElementType;
+        var deferredJsxStatelessElementType;
+        var deferredNodes;
+        var deferredUnusedIdentifierNodes;
+        var flowLoopStart = 0;
+        var flowLoopCount = 0;
+        var sharedFlowCount = 0;
+        var flowAnalysisDisabled = false;
+        var emptyStringType = getLiteralType("");
+        var zeroType = getLiteralType(0);
+        var resolutionTargets = [];
+        var resolutionResults = [];
+        var resolutionPropertyNames = [];
+        var suggestionCount = 0;
+        var maximumSuggestionCount = 10;
+        var mergedSymbols = [];
+        var symbolLinks = [];
+        var nodeLinks = [];
+        var flowLoopCaches = [];
+        var flowLoopNodes = [];
+        var flowLoopKeys = [];
+        var flowLoopTypes = [];
+        var sharedFlowNodes = [];
+        var sharedFlowTypes = [];
+        var potentialThisCollisions = [];
+        var potentialNewTargetCollisions = [];
+        var awaitedTypeStack = [];
+        var diagnostics = ts.createDiagnosticCollection();
+        var TypeFacts;
+        (function (TypeFacts) {
+            TypeFacts[TypeFacts["None"] = 0] = "None";
+            TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString";
+            TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber";
+            TypeFacts[TypeFacts["TypeofEQBoolean"] = 4] = "TypeofEQBoolean";
+            TypeFacts[TypeFacts["TypeofEQSymbol"] = 8] = "TypeofEQSymbol";
+            TypeFacts[TypeFacts["TypeofEQObject"] = 16] = "TypeofEQObject";
+            TypeFacts[TypeFacts["TypeofEQFunction"] = 32] = "TypeofEQFunction";
+            TypeFacts[TypeFacts["TypeofEQHostObject"] = 64] = "TypeofEQHostObject";
+            TypeFacts[TypeFacts["TypeofNEString"] = 128] = "TypeofNEString";
+            TypeFacts[TypeFacts["TypeofNENumber"] = 256] = "TypeofNENumber";
+            TypeFacts[TypeFacts["TypeofNEBoolean"] = 512] = "TypeofNEBoolean";
+            TypeFacts[TypeFacts["TypeofNESymbol"] = 1024] = "TypeofNESymbol";
+            TypeFacts[TypeFacts["TypeofNEObject"] = 2048] = "TypeofNEObject";
+            TypeFacts[TypeFacts["TypeofNEFunction"] = 4096] = "TypeofNEFunction";
+            TypeFacts[TypeFacts["TypeofNEHostObject"] = 8192] = "TypeofNEHostObject";
+            TypeFacts[TypeFacts["EQUndefined"] = 16384] = "EQUndefined";
+            TypeFacts[TypeFacts["EQNull"] = 32768] = "EQNull";
+            TypeFacts[TypeFacts["EQUndefinedOrNull"] = 65536] = "EQUndefinedOrNull";
+            TypeFacts[TypeFacts["NEUndefined"] = 131072] = "NEUndefined";
+            TypeFacts[TypeFacts["NENull"] = 262144] = "NENull";
+            TypeFacts[TypeFacts["NEUndefinedOrNull"] = 524288] = "NEUndefinedOrNull";
+            TypeFacts[TypeFacts["Truthy"] = 1048576] = "Truthy";
+            TypeFacts[TypeFacts["Falsy"] = 2097152] = "Falsy";
+            TypeFacts[TypeFacts["Discriminatable"] = 4194304] = "Discriminatable";
+            TypeFacts[TypeFacts["All"] = 8388607] = "All";
+            // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
+            // The presence of a particular fact means that the given test is true for some (and possibly all) values
+            // of that kind of type.
+            TypeFacts[TypeFacts["BaseStringStrictFacts"] = 933633] = "BaseStringStrictFacts";
+            TypeFacts[TypeFacts["BaseStringFacts"] = 3145473] = "BaseStringFacts";
+            TypeFacts[TypeFacts["StringStrictFacts"] = 4079361] = "StringStrictFacts";
+            TypeFacts[TypeFacts["StringFacts"] = 4194049] = "StringFacts";
+            TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 3030785] = "EmptyStringStrictFacts";
+            TypeFacts[TypeFacts["EmptyStringFacts"] = 3145473] = "EmptyStringFacts";
+            TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 1982209] = "NonEmptyStringStrictFacts";
+            TypeFacts[TypeFacts["NonEmptyStringFacts"] = 4194049] = "NonEmptyStringFacts";
+            TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 933506] = "BaseNumberStrictFacts";
+            TypeFacts[TypeFacts["BaseNumberFacts"] = 3145346] = "BaseNumberFacts";
+            TypeFacts[TypeFacts["NumberStrictFacts"] = 4079234] = "NumberStrictFacts";
+            TypeFacts[TypeFacts["NumberFacts"] = 4193922] = "NumberFacts";
+            TypeFacts[TypeFacts["ZeroStrictFacts"] = 3030658] = "ZeroStrictFacts";
+            TypeFacts[TypeFacts["ZeroFacts"] = 3145346] = "ZeroFacts";
+            TypeFacts[TypeFacts["NonZeroStrictFacts"] = 1982082] = "NonZeroStrictFacts";
+            TypeFacts[TypeFacts["NonZeroFacts"] = 4193922] = "NonZeroFacts";
+            TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 933252] = "BaseBooleanStrictFacts";
+            TypeFacts[TypeFacts["BaseBooleanFacts"] = 3145092] = "BaseBooleanFacts";
+            TypeFacts[TypeFacts["BooleanStrictFacts"] = 4078980] = "BooleanStrictFacts";
+            TypeFacts[TypeFacts["BooleanFacts"] = 4193668] = "BooleanFacts";
+            TypeFacts[TypeFacts["FalseStrictFacts"] = 3030404] = "FalseStrictFacts";
+            TypeFacts[TypeFacts["FalseFacts"] = 3145092] = "FalseFacts";
+            TypeFacts[TypeFacts["TrueStrictFacts"] = 1981828] = "TrueStrictFacts";
+            TypeFacts[TypeFacts["TrueFacts"] = 4193668] = "TrueFacts";
+            TypeFacts[TypeFacts["SymbolStrictFacts"] = 1981320] = "SymbolStrictFacts";
+            TypeFacts[TypeFacts["SymbolFacts"] = 4193160] = "SymbolFacts";
+            TypeFacts[TypeFacts["ObjectStrictFacts"] = 6166480] = "ObjectStrictFacts";
+            TypeFacts[TypeFacts["ObjectFacts"] = 8378320] = "ObjectFacts";
+            TypeFacts[TypeFacts["FunctionStrictFacts"] = 6164448] = "FunctionStrictFacts";
+            TypeFacts[TypeFacts["FunctionFacts"] = 8376288] = "FunctionFacts";
+            TypeFacts[TypeFacts["UndefinedFacts"] = 2457472] = "UndefinedFacts";
+            TypeFacts[TypeFacts["NullFacts"] = 2340752] = "NullFacts";
+        })(TypeFacts || (TypeFacts = {}));
+        var typeofEQFacts = ts.createMapFromTemplate({
+            "string": 1 /* TypeofEQString */,
+            "number": 2 /* TypeofEQNumber */,
+            "boolean": 4 /* TypeofEQBoolean */,
+            "symbol": 8 /* TypeofEQSymbol */,
+            "undefined": 16384 /* EQUndefined */,
+            "object": 16 /* TypeofEQObject */,
+            "function": 32 /* TypeofEQFunction */
+        });
+        var typeofNEFacts = ts.createMapFromTemplate({
+            "string": 128 /* TypeofNEString */,
+            "number": 256 /* TypeofNENumber */,
+            "boolean": 512 /* TypeofNEBoolean */,
+            "symbol": 1024 /* TypeofNESymbol */,
+            "undefined": 131072 /* NEUndefined */,
+            "object": 2048 /* TypeofNEObject */,
+            "function": 4096 /* TypeofNEFunction */
+        });
+        var typeofTypesByName = ts.createMapFromTemplate({
+            "string": stringType,
+            "number": numberType,
+            "boolean": booleanType,
+            "symbol": esSymbolType,
+            "undefined": undefinedType
+        });
+        var typeofType = createTypeofType();
+        var _jsxNamespace;
+        var _jsxFactoryEntity;
+        var _jsxElementPropertiesName;
+        var _hasComputedJsxElementPropertiesName = false;
+        var _jsxElementChildrenPropertyName;
+        var _hasComputedJsxElementChildrenPropertyName = false;
+        /** Things we lazy load from the JSX namespace */
+        var jsxTypes = ts.createUnderscoreEscapedMap();
+        var JsxNames = {
+            JSX: "JSX",
+            IntrinsicElements: "IntrinsicElements",
+            ElementClass: "ElementClass",
+            ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
+            ElementChildrenAttributeNameContainer: "ElementChildrenAttribute",
+            Element: "Element",
+            IntrinsicAttributes: "IntrinsicAttributes",
+            IntrinsicClassAttributes: "IntrinsicClassAttributes"
+        };
+        var subtypeRelation = ts.createMap();
+        var assignableRelation = ts.createMap();
+        var comparableRelation = ts.createMap();
+        var identityRelation = ts.createMap();
+        var enumRelation = ts.createMap();
+        // This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
+        var _displayBuilder;
+        var TypeSystemPropertyName;
+        (function (TypeSystemPropertyName) {
+            TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type";
+            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType";
+            TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType";
+            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType";
+        })(TypeSystemPropertyName || (TypeSystemPropertyName = {}));
+        var CheckMode;
+        (function (CheckMode) {
+            CheckMode[CheckMode["Normal"] = 0] = "Normal";
+            CheckMode[CheckMode["SkipContextSensitive"] = 1] = "SkipContextSensitive";
+            CheckMode[CheckMode["Inferential"] = 2] = "Inferential";
+        })(CheckMode || (CheckMode = {}));
+        var CallbackCheck;
+        (function (CallbackCheck) {
+            CallbackCheck[CallbackCheck["None"] = 0] = "None";
+            CallbackCheck[CallbackCheck["Bivariant"] = 1] = "Bivariant";
+            CallbackCheck[CallbackCheck["Strict"] = 2] = "Strict";
+        })(CallbackCheck || (CallbackCheck = {}));
+        var builtinGlobals = ts.createSymbolTable();
+        builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
+        var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor);
+        initializeTypeChecker();
+        return checker;
+        function getJsxNamespace() {
+            if (!_jsxNamespace) {
+                _jsxNamespace = "React";
+                if (compilerOptions.jsxFactory) {
+                    _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
+                    if (_jsxFactoryEntity) {
+                        _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
+                    }
+                }
+                else if (compilerOptions.reactNamespace) {
+                    _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace);
+                }
+            }
+            return _jsxNamespace;
+        }
+        function getEmitResolver(sourceFile, cancellationToken) {
+            // Ensure we have all the type information in place for this file so that all the
+            // emitter questions of this resolver will return the right information.
+            getDiagnostics(sourceFile, cancellationToken);
+            return emitResolver;
+        }
+        function error(location, message, arg0, arg1, arg2) {
+            var diagnostic = location
+                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2)
+                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2);
+            diagnostics.add(diagnostic);
+        }
+        function createSymbol(flags, name) {
+            symbolCount++;
+            var symbol = (new Symbol(flags | 33554432 /* Transient */, name));
+            symbol.checkFlags = 0;
+            return symbol;
+        }
+        function isTransientSymbol(symbol) {
+            return (symbol.flags & 33554432 /* Transient */) !== 0;
+        }
+        function getExcludedSymbolFlags(flags) {
+            var result = 0;
+            if (flags & 2 /* BlockScopedVariable */)
+                result |= 107455 /* BlockScopedVariableExcludes */;
+            if (flags & 1 /* FunctionScopedVariable */)
+                result |= 107454 /* FunctionScopedVariableExcludes */;
+            if (flags & 4 /* Property */)
+                result |= 0 /* PropertyExcludes */;
+            if (flags & 8 /* EnumMember */)
+                result |= 900095 /* EnumMemberExcludes */;
+            if (flags & 16 /* Function */)
+                result |= 106927 /* FunctionExcludes */;
+            if (flags & 32 /* Class */)
+                result |= 899519 /* ClassExcludes */;
+            if (flags & 64 /* Interface */)
+                result |= 792968 /* InterfaceExcludes */;
+            if (flags & 256 /* RegularEnum */)
+                result |= 899327 /* RegularEnumExcludes */;
+            if (flags & 128 /* ConstEnum */)
+                result |= 899967 /* ConstEnumExcludes */;
+            if (flags & 512 /* ValueModule */)
+                result |= 106639 /* ValueModuleExcludes */;
+            if (flags & 8192 /* Method */)
+                result |= 99263 /* MethodExcludes */;
+            if (flags & 32768 /* GetAccessor */)
+                result |= 41919 /* GetAccessorExcludes */;
+            if (flags & 65536 /* SetAccessor */)
+                result |= 74687 /* SetAccessorExcludes */;
+            if (flags & 262144 /* TypeParameter */)
+                result |= 530920 /* TypeParameterExcludes */;
+            if (flags & 524288 /* TypeAlias */)
+                result |= 793064 /* TypeAliasExcludes */;
+            if (flags & 2097152 /* Alias */)
+                result |= 2097152 /* AliasExcludes */;
+            return result;
+        }
+        function recordMergedSymbol(target, source) {
+            if (!source.mergeId) {
+                source.mergeId = nextMergeId;
+                nextMergeId++;
+            }
+            mergedSymbols[source.mergeId] = target;
+        }
+        function cloneSymbol(symbol) {
+            var result = createSymbol(symbol.flags, symbol.escapedName);
+            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
+            result.parent = symbol.parent;
+            if (symbol.valueDeclaration)
+                result.valueDeclaration = symbol.valueDeclaration;
+            if (symbol.constEnumOnlyModule)
+                result.constEnumOnlyModule = true;
+            if (symbol.members)
+                result.members = ts.cloneMap(symbol.members);
+            if (symbol.exports)
+                result.exports = ts.cloneMap(symbol.exports);
+            recordMergedSymbol(result, symbol);
+            return result;
+        }
+        function mergeSymbol(target, source) {
+            if (!(target.flags & getExcludedSymbolFlags(source.flags))) {
+                if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
+                    // reset flag when merging instantiated module into value module that has only const enums
+                    target.constEnumOnlyModule = false;
+                }
+                target.flags |= source.flags;
+                if (source.valueDeclaration &&
+                    (!target.valueDeclaration ||
+                        (target.valueDeclaration.kind === 233 /* ModuleDeclaration */ && source.valueDeclaration.kind !== 233 /* ModuleDeclaration */))) {
+                    // other kinds of value declarations take precedence over modules
+                    target.valueDeclaration = source.valueDeclaration;
+                }
+                ts.addRange(target.declarations, source.declarations);
+                if (source.members) {
+                    if (!target.members)
+                        target.members = ts.createSymbolTable();
+                    mergeSymbolTable(target.members, source.members);
+                }
+                if (source.exports) {
+                    if (!target.exports)
+                        target.exports = ts.createSymbolTable();
+                    mergeSymbolTable(target.exports, source.exports);
+                }
+                recordMergedSymbol(target, source);
+            }
+            else if (target.flags & 1024 /* NamespaceModule */) {
+                error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
+            }
+            else {
+                var message_2 = target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */
+                    ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
+                ts.forEach(source.declarations, function (node) {
+                    error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source));
+                });
+                ts.forEach(target.declarations, function (node) {
+                    error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source));
+                });
+            }
+        }
+        function mergeSymbolTable(target, source) {
+            source.forEach(function (sourceSymbol, id) {
+                var targetSymbol = target.get(id);
+                if (!targetSymbol) {
+                    target.set(id, sourceSymbol);
+                }
+                else {
+                    if (!(targetSymbol.flags & 33554432 /* Transient */)) {
+                        targetSymbol = cloneSymbol(targetSymbol);
+                        target.set(id, targetSymbol);
+                    }
+                    mergeSymbol(targetSymbol, sourceSymbol);
+                }
+            });
+        }
+        function mergeModuleAugmentation(moduleName) {
+            var moduleAugmentation = moduleName.parent;
+            if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
+                // this is a combined symbol for multiple augmentations within the same file.
+                // its symbol already has accumulated information for all declarations
+                // so we need to add it just once - do the work only for first declaration
+                ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1);
+                return;
+            }
+            if (ts.isGlobalScopeAugmentation(moduleAugmentation)) {
+                mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
+            }
+            else {
+                // find a module that about to be augmented
+                // do not validate names of augmentations that are defined in ambient context
+                var moduleNotFoundError = !ts.isInAmbientContext(moduleName.parent.parent)
+                    ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
+                    : undefined;
+                var mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
+                if (!mainModule) {
+                    return;
+                }
+                // obtain item referenced by 'export='
+                mainModule = resolveExternalModuleSymbol(mainModule);
+                if (mainModule.flags & 1920 /* Namespace */) {
+                    // if module symbol has already been merged - it is safe to use it.
+                    // otherwise clone it
+                    mainModule = mainModule.flags & 33554432 /* Transient */ ? mainModule : cloneSymbol(mainModule);
+                    mergeSymbol(mainModule, moduleAugmentation.symbol);
+                }
+                else {
+                    // moduleName will be a StringLiteral since this is not `declare global`.
+                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
+                }
+            }
+        }
+        function addToSymbolTable(target, source, message) {
+            source.forEach(function (sourceSymbol, id) {
+                var targetSymbol = target.get(id);
+                if (targetSymbol) {
+                    // Error on redeclarations
+                    ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message));
+                }
+                else {
+                    target.set(id, sourceSymbol);
+                }
+            });
+            function addDeclarationDiagnostic(id, message) {
+                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
+            }
+        }
+        function getSymbolLinks(symbol) {
+            if (symbol.flags & 33554432 /* Transient */)
+                return symbol;
+            var id = getSymbolId(symbol);
+            return symbolLinks[id] || (symbolLinks[id] = {});
+        }
+        function getNodeLinks(node) {
+            var nodeId = getNodeId(node);
+            return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 });
+        }
+        function getObjectFlags(type) {
+            return type.flags & 32768 /* Object */ ? type.objectFlags : 0;
+        }
+        function isGlobalSourceFile(node) {
+            return node.kind === 265 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
+        }
+        function getSymbol(symbols, name, meaning) {
+            if (meaning) {
+                var symbol = symbols.get(name);
+                if (symbol) {
+                    ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
+                    if (symbol.flags & meaning) {
+                        return symbol;
+                    }
+                    if (symbol.flags & 2097152 /* Alias */) {
+                        var target = resolveAlias(symbol);
+                        // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
+                        if (target === unknownSymbol || target.flags & meaning) {
+                            return symbol;
+                        }
+                    }
+                }
+            }
+            // return undefined if we can't find a symbol.
+        }
+        /**
+         * Get symbols that represent parameter-property-declaration as parameter and as property declaration
+         * @param parameter a parameterDeclaration node
+         * @param parameterName a name of the parameter to get the symbols for.
+         * @return a tuple of two symbols
+         */
+        function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) {
+            var constructorDeclaration = parameter.parent;
+            var classDeclaration = parameter.parent.parent;
+            var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 107455 /* Value */);
+            var propertySymbol = getSymbol(classDeclaration.symbol.members, parameterName, 107455 /* Value */);
+            if (parameterSymbol && propertySymbol) {
+                return [parameterSymbol, propertySymbol];
+            }
+            ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration");
+        }
+        function isBlockScopedNameDeclaredBeforeUse(declaration, usage) {
+            var declarationFile = ts.getSourceFileOfNode(declaration);
+            var useFile = ts.getSourceFileOfNode(usage);
+            if (declarationFile !== useFile) {
+                if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
+                    (!compilerOptions.outFile && !compilerOptions.out) ||
+                    isInTypeQuery(usage) ||
+                    ts.isInAmbientContext(declaration)) {
+                    // nodes are in different files and order cannot be determined
+                    return true;
+                }
+                // declaration is after usage
+                // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
+                if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
+                    return true;
+                }
+                var sourceFiles = host.getSourceFiles();
+                return ts.indexOf(sourceFiles, declarationFile) <= ts.indexOf(sourceFiles, useFile);
+            }
+            if (declaration.pos <= usage.pos) {
+                // declaration is before usage
+                if (declaration.kind === 176 /* BindingElement */) {
+                    // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
+                    var errorBindingElement = ts.getAncestor(usage, 176 /* BindingElement */);
+                    if (errorBindingElement) {
+                        return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) ||
+                            declaration.pos < errorBindingElement.pos;
+                    }
+                    // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
+                    return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 226 /* VariableDeclaration */), usage);
+                }
+                else if (declaration.kind === 226 /* VariableDeclaration */) {
+                    // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
+                    return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
+                }
+                return true;
+            }
+            // declaration is after usage, but it can still be legal if usage is deferred:
+            // 1. inside an export specifier
+            // 2. inside a function
+            // 3. inside an instance property initializer, a reference to a non-instance property
+            // 4. inside a static property initializer, a reference to a static method in the same class
+            // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
+            // or if usage is in a type context:
+            // 1. inside a type query (typeof in type position)
+            if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* ExportAssignment */ && usage.parent.isExportEquals)) {
+                // export specifiers do not use the variable, they only make it available for use
+                return true;
+            }
+            // When resolving symbols for exports, the `usage` location passed in can be the export site directly
+            if (usage.kind === 243 /* ExportAssignment */ && usage.isExportEquals) {
+                return true;
+            }
+            var container = ts.getEnclosingBlockScopeContainer(declaration);
+            return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
+            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
+                var container = ts.getEnclosingBlockScopeContainer(declaration);
+                switch (declaration.parent.parent.kind) {
+                    case 208 /* VariableStatement */:
+                    case 214 /* ForStatement */:
+                    case 216 /* ForOfStatement */:
+                        // variable statement/for/for-of statement case,
+                        // use site should not be inside variable declaration (initializer of declaration or binding element)
+                        if (isSameScopeDescendentOf(usage, declaration, container)) {
+                            return true;
+                        }
+                        break;
+                }
+                // ForIn/ForOf case - use site should not be used in expression part
+                return ts.isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container);
+            }
+            function isUsedInFunctionOrInstanceProperty(usage, declaration, container) {
+                return !!ts.findAncestor(usage, function (current) {
+                    if (current === container) {
+                        return "quit";
+                    }
+                    if (ts.isFunctionLike(current)) {
+                        return true;
+                    }
+                    var initializerOfProperty = current.parent &&
+                        current.parent.kind === 149 /* PropertyDeclaration */ &&
+                        current.parent.initializer === current;
+                    if (initializerOfProperty) {
+                        if (ts.hasModifier(current.parent, 32 /* Static */)) {
+                            if (declaration.kind === 151 /* MethodDeclaration */) {
+                                return true;
+                            }
+                        }
+                        else {
+                            var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */);
+                            if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) {
+                                return true;
+                            }
+                        }
+                    }
+                });
+            }
+        }
+        /**
+         * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
+         * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
+         * the given name can be found.
+         *
+         * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters.
+         */
+        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, suggestedNameNotFoundMessage) {
+            return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage);
+        }
+        function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, lookup, suggestedNameNotFoundMessage) {
+            var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
+            var result;
+            var lastLocation;
+            var lastNonBlockLocation;
+            var propertyWithInvalidInitializer;
+            var errorLocation = location;
+            var grandparent;
+            var isInExternalModule = false;
+            loop: while (location) {
+                // Locals of a source file are not in scope (because they get merged into the global symbol table)
+                if (location.locals && !isGlobalSourceFile(location)) {
+                    if (result = lookup(location.locals, name, meaning)) {
+                        var useResult = true;
+                        if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
+                            // symbol lookup restrictions for function-like declarations
+                            // - Type parameters of a function are in scope in the entire function declaration, including the parameter
+                            //   list and return type. However, local types are only in scope in the function body.
+                            // - parameters are only in the scope of function body
+                            // This restriction does not apply to JSDoc comment types because they are parented
+                            // at a higher level than type parameters would normally be
+                            if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 275 /* JSDocComment */) {
+                                useResult = result.flags & 262144 /* TypeParameter */
+                                    // type parameters are visible in parameter list, return type and type parameter list
+                                    ? lastLocation === location.type ||
+                                        lastLocation.kind === 146 /* Parameter */ ||
+                                        lastLocation.kind === 145 /* TypeParameter */
+                                    // local types not visible outside the function body
+                                    : false;
+                            }
+                            if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) {
+                                // parameters are visible only inside function body, parameter list and return type
+                                // technically for parameter list case here we might mix parameters and variables declared in function,
+                                // however it is detected separately when checking initializers of parameters
+                                // to make sure that they reference no variables declared after them.
+                                useResult =
+                                    lastLocation.kind === 146 /* Parameter */ ||
+                                        (lastLocation === location.type &&
+                                            result.valueDeclaration.kind === 146 /* Parameter */);
+                            }
+                        }
+                        if (useResult) {
+                            break loop;
+                        }
+                        else {
+                            result = undefined;
+                        }
+                    }
+                }
+                switch (location.kind) {
+                    case 265 /* SourceFile */:
+                        if (!ts.isExternalOrCommonJsModule(location))
+                            break;
+                        isInExternalModule = true;
+                    // falls through
+                    case 233 /* ModuleDeclaration */:
+                        var moduleExports = getSymbolOfNode(location).exports;
+                        if (location.kind === 265 /* SourceFile */ || ts.isAmbientModule(location)) {
+                            // It's an external module. First see if the module has an export default and if the local
+                            // name of that export default matches.
+                            if (result = moduleExports.get("default")) {
+                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
+                                if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
+                                    break loop;
+                                }
+                                result = undefined;
+                            }
+                            // Because of module/namespace merging, a module's exports are in scope,
+                            // yet we never want to treat an export specifier as putting a member in scope.
+                            // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
+                            // Two things to note about this:
+                            //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
+                            //        on an export specifier is that it might find the export specifier itself, and try to
+                            //        resolve it as an alias. This will cause the checker to consider the export specifier
+                            //        a circular alias reference when it might not be.
+                            //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
+                            //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
+                            //        which is not the desired behavior.
+                            var moduleExport = moduleExports.get(name);
+                            if (moduleExport &&
+                                moduleExport.flags === 2097152 /* Alias */ &&
+                                ts.getDeclarationOfKind(moduleExport, 246 /* ExportSpecifier */)) {
+                                break;
+                            }
+                        }
+                        if (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */)) {
+                            break loop;
+                        }
+                        break;
+                    case 232 /* EnumDeclaration */:
+                        if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
+                            break loop;
+                        }
+                        break;
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                        // TypeScript 1.0 spec (April 2014): 8.4.1
+                        // Initializer expressions for instance member variables are evaluated in the scope
+                        // of the class constructor body but are not permitted to reference parameters or
+                        // local variables of the constructor. This effectively means that entities from outer scopes
+                        // by the same name as a constructor parameter or local variable are inaccessible
+                        // in initializer expressions for instance member variables.
+                        if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32 /* Static */)) {
+                            var ctor = findConstructorDeclaration(location.parent);
+                            if (ctor && ctor.locals) {
+                                if (lookup(ctor.locals, name, meaning & 107455 /* Value */)) {
+                                    // Remember the property node, it will be used later to report appropriate error
+                                    propertyWithInvalidInitializer = location;
+                                }
+                            }
+                        }
+                        break;
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                        if (result = lookup(getSymbolOfNode(location).members, name, meaning & 793064 /* Type */)) {
+                            if (!isTypeParameterSymbolDeclaredInContainer(result, location)) {
+                                // ignore type parameters not declared in this container
+                                result = undefined;
+                                break;
+                            }
+                            if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) {
+                                // TypeScript 1.0 spec (April 2014): 3.4.1
+                                // The scope of a type parameter extends over the entire declaration with which the type
+                                // parameter list is associated, with the exception of static member declarations in classes.
+                                error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
+                                return undefined;
+                            }
+                            break loop;
+                        }
+                        if (location.kind === 199 /* ClassExpression */ && meaning & 32 /* Class */) {
+                            var className = location.name;
+                            if (className && name === className.escapedText) {
+                                result = location.symbol;
+                                break loop;
+                            }
+                        }
+                        break;
+                    case 201 /* ExpressionWithTypeArguments */:
+                        // The type parameters of a class are not in scope in the base class expression.
+                        if (lastLocation === location.expression && location.parent.token === 85 /* ExtendsKeyword */) {
+                            var container = location.parent.parent;
+                            if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 793064 /* Type */))) {
+                                if (nameNotFoundMessage) {
+                                    error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
+                                }
+                                return undefined;
+                            }
+                        }
+                        break;
+                    // It is not legal to reference a class's own type parameters from a computed property name that
+                    // belongs to the class. For example:
+                    //
+                    //   function foo<T>() { return '' }
+                    //   class C<T> { // <-- Class's own type parameter T
+                    //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
+                    //   }
+                    //
+                    case 144 /* ComputedPropertyName */:
+                        grandparent = location.parent.parent;
+                        if (ts.isClassLike(grandparent) || grandparent.kind === 230 /* InterfaceDeclaration */) {
+                            // A reference to this grandparent's type parameters would be an error
+                            if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 793064 /* Type */)) {
+                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
+                                return undefined;
+                            }
+                        }
+                        break;
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    case 152 /* Constructor */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 228 /* FunctionDeclaration */:
+                    case 187 /* ArrowFunction */:
+                        if (meaning & 3 /* Variable */ && name === "arguments") {
+                            result = argumentsSymbol;
+                            break loop;
+                        }
+                        break;
+                    case 186 /* FunctionExpression */:
+                        if (meaning & 3 /* Variable */ && name === "arguments") {
+                            result = argumentsSymbol;
+                            break loop;
+                        }
+                        if (meaning & 16 /* Function */) {
+                            var functionName = location.name;
+                            if (functionName && name === functionName.escapedText) {
+                                result = location.symbol;
+                                break loop;
+                            }
+                        }
+                        break;
+                    case 147 /* Decorator */:
+                        // Decorators are resolved at the class declaration. Resolving at the parameter
+                        // or member would result in looking up locals in the method.
+                        //
+                        //   function y() {}
+                        //   class C {
+                        //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
+                        //   }
+                        //
+                        if (location.parent && location.parent.kind === 146 /* Parameter */) {
+                            location = location.parent;
+                        }
+                        //
+                        //   function y() {}
+                        //   class C {
+                        //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
+                        //   }
+                        //
+                        if (location.parent && ts.isClassElement(location.parent)) {
+                            location = location.parent;
+                        }
+                        break;
+                }
+                if (location.kind !== 207 /* Block */) {
+                    lastNonBlockLocation = location;
+                }
+                lastLocation = location;
+                location = location.parent;
+            }
+            // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
+            // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself.
+            // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
+            if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) {
+                result.isReferenced = true;
+            }
+            if (!result) {
+                if (lastLocation) {
+                    ts.Debug.assert(lastLocation.kind === 265 /* SourceFile */);
+                    if (lastLocation.commonJsModuleIndicator && name === "exports") {
+                        return lastLocation.symbol;
+                    }
+                }
+                result = lookup(globals, name, meaning);
+            }
+            if (!result) {
+                if (nameNotFoundMessage) {
+                    if (!errorLocation ||
+                        !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
+                            !checkAndReportErrorForExtendingInterface(errorLocation) &&
+                            !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
+                            !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
+                            !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) {
+                        var suggestion = void 0;
+                        if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
+                            suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning);
+                            if (suggestion) {
+                                error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestion);
+                            }
+                        }
+                        if (!suggestion) {
+                            error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
+                        }
+                        suggestionCount++;
+                    }
+                }
+                return undefined;
+            }
+            // Perform extra checks only if error reporting was requested
+            if (nameNotFoundMessage) {
+                if (propertyWithInvalidInitializer) {
+                    // We have a match, but the reference occurred within a property initializer and the identifier also binds
+                    // to a local variable in the constructor where the code will be emitted.
+                    var propertyName = propertyWithInvalidInitializer.name;
+                    error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg));
+                    return undefined;
+                }
+                // Only check for block-scoped variable if we have an error location and are looking for the
+                // name with variable meaning
+                //      For example,
+                //          declare module foo {
+                //              interface bar {}
+                //          }
+                //      const foo/*1*/: foo/*2*/.bar;
+                // The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
+                // block-scoped variable and namespace module. However, only when we
+                // try to resolve name in /*1*/ which is used in variable position,
+                // we want to check for block-scoped
+                if (errorLocation &&
+                    (meaning & 2 /* BlockScopedVariable */ ||
+                        ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 107455 /* Value */) === 107455 /* Value */))) {
+                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
+                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) {
+                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
+                    }
+                }
+                // If we're in an external module, we can't reference value symbols created from UMD export declarations
+                if (result && isInExternalModule && (meaning & 107455 /* Value */) === 107455 /* Value */) {
+                    var decls = result.declarations;
+                    if (decls && decls.length === 1 && decls[0].kind === 236 /* NamespaceExportDeclaration */) {
+                        error(errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name));
+                    }
+                }
+            }
+            return result;
+        }
+        function diagnosticName(nameArg) {
+            return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg);
+        }
+        function isTypeParameterSymbolDeclaredInContainer(symbol, container) {
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var decl = _a[_i];
+                if (decl.kind === 145 /* TypeParameter */ && decl.parent === container) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
+            if ((errorLocation.kind === 71 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) {
+                return false;
+            }
+            var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ true);
+            var location = container;
+            while (location) {
+                if (ts.isClassLike(location.parent)) {
+                    var classSymbol = getSymbolOfNode(location.parent);
+                    if (!classSymbol) {
+                        break;
+                    }
+                    // Check to see if a static member exists.
+                    var constructorType = getTypeOfSymbol(classSymbol);
+                    if (getPropertyOfType(constructorType, name)) {
+                        error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol));
+                        return true;
+                    }
+                    // No static member is present.
+                    // Check if we're in an instance method and look for a relevant instance member.
+                    if (location === container && !ts.hasModifier(location, 32 /* Static */)) {
+                        var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType;
+                        if (getPropertyOfType(instanceType, name)) {
+                            error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg));
+                            return true;
+                        }
+                    }
+                }
+                location = location.parent;
+            }
+            return false;
+        }
+        function checkAndReportErrorForExtendingInterface(errorLocation) {
+            var expression = getEntityNameForExtendingInterface(errorLocation);
+            var isError = !!(expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true));
+            if (isError) {
+                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
+            }
+            return isError;
+        }
+        /**
+         * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
+         * but returns undefined if that expression is not an EntityNameExpression.
+         */
+        function getEntityNameForExtendingInterface(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                case 179 /* PropertyAccessExpression */:
+                    return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
+                case 201 /* ExpressionWithTypeArguments */:
+                    if (ts.isEntityNameExpression(node.expression)) {
+                        return node.expression;
+                    }
+                // falls through
+                default:
+                    return undefined;
+            }
+        }
+        function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) {
+            if (meaning === 1920 /* Namespace */) {
+                var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
+                var parent = errorLocation.parent;
+                if (symbol) {
+                    if (ts.isQualifiedName(parent)) {
+                        ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace");
+                        var propName = parent.right.escapedText;
+                        var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName);
+                        if (propType) {
+                            error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName));
+                            return true;
+                        }
+                    }
+                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name));
+                    return true;
+                }
+            }
+            return false;
+        }
+        function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) {
+            if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */)) {
+                if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") {
+                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
+                    return true;
+                }
+                var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
+                if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) {
+                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
+                    return true;
+                }
+            }
+            return false;
+        }
+        function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) {
+            if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */ & ~793064 /* Type */)) {
+                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
+                if (symbol) {
+                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name));
+                    return true;
+                }
+            }
+            else if (meaning & (793064 /* Type */ & ~1024 /* NamespaceModule */ & ~107455 /* Value */)) {
+                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~793064 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
+                if (symbol) {
+                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name));
+                    return true;
+                }
+            }
+            return false;
+        }
+        function checkResolvedBlockScopedVariable(result, errorLocation) {
+            ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */));
+            // Block-scoped variables cannot be used before their definition
+            var declaration = ts.forEach(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 232 /* EnumDeclaration */) ? d : undefined; });
+            ts.Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined");
+            if (!ts.isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
+                if (result.flags & 2 /* BlockScopedVariable */) {
+                    error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
+                }
+                else if (result.flags & 32 /* Class */) {
+                    error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
+                }
+                else if (result.flags & 256 /* RegularEnum */) {
+                    error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
+                }
+            }
+        }
+        /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached.
+         * If at any point current node is equal to 'parent' node - return true.
+         * Return false if 'stopAt' node is reached or isFunctionLike(current) === true.
+         */
+        function isSameScopeDescendentOf(initial, parent, stopAt) {
+            return parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; });
+        }
+        function getAnyImportSyntax(node) {
+            switch (node.kind) {
+                case 237 /* ImportEqualsDeclaration */:
+                    return node;
+                case 239 /* ImportClause */:
+                    return node.parent;
+                case 240 /* NamespaceImport */:
+                    return node.parent.parent;
+                case 242 /* ImportSpecifier */:
+                    return node.parent.parent.parent;
+                default:
+                    return undefined;
+            }
+        }
+        function getDeclarationOfAliasSymbol(symbol) {
+            return ts.find(symbol.declarations, ts.isAliasSymbolDeclaration);
+        }
+        function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) {
+            if (node.moduleReference.kind === 248 /* ExternalModuleReference */) {
+                return resolveExternalModuleSymbol(resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node)));
+            }
+            return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
+        }
+        function getTargetOfImportClause(node, dontResolveAlias) {
+            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
+            if (moduleSymbol) {
+                var exportDefaultSymbol = void 0;
+                if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
+                    exportDefaultSymbol = moduleSymbol;
+                }
+                else {
+                    var exportValue = moduleSymbol.exports.get("export=");
+                    exportDefaultSymbol = exportValue
+                        ? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
+                        : resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
+                }
+                if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
+                    error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
+                }
+                else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
+                    return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
+                }
+                return exportDefaultSymbol;
+            }
+        }
+        function getTargetOfNamespaceImport(node, dontResolveAlias) {
+            var moduleSpecifier = node.parent.parent.moduleSpecifier;
+            return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
+        }
+        // This function creates a synthetic symbol that combines the value side of one symbol with the
+        // type/namespace side of another symbol. Consider this example:
+        //
+        //   declare module graphics {
+        //       interface Point {
+        //           x: number;
+        //           y: number;
+        //       }
+        //   }
+        //   declare var graphics: {
+        //       Point: new (x: number, y: number) => graphics.Point;
+        //   }
+        //   declare module "graphics" {
+        //       export = graphics;
+        //   }
+        //
+        // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
+        // property with the type/namespace side interface 'Point'.
+        function combineValueAndTypeSymbols(valueSymbol, typeSymbol) {
+            if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
+                return unknownSymbol;
+            }
+            if (valueSymbol.flags & (793064 /* Type */ | 1920 /* Namespace */)) {
+                return valueSymbol;
+            }
+            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
+            result.declarations = ts.concatenate(valueSymbol.declarations, typeSymbol.declarations);
+            result.parent = valueSymbol.parent || typeSymbol.parent;
+            if (valueSymbol.valueDeclaration)
+                result.valueDeclaration = valueSymbol.valueDeclaration;
+            if (typeSymbol.members)
+                result.members = typeSymbol.members;
+            if (valueSymbol.exports)
+                result.exports = valueSymbol.exports;
+            return result;
+        }
+        function getExportOfModule(symbol, name, dontResolveAlias) {
+            if (symbol.flags & 1536 /* Module */) {
+                return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
+            }
+        }
+        function getPropertyOfVariable(symbol, name) {
+            if (symbol.flags & 3 /* Variable */) {
+                var typeAnnotation = symbol.valueDeclaration.type;
+                if (typeAnnotation) {
+                    return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
+                }
+            }
+        }
+        function getExternalModuleMember(node, specifier, dontResolveAlias) {
+            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
+            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
+            if (targetSymbol) {
+                var name = specifier.propertyName || specifier.name;
+                if (name.escapedText) {
+                    if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
+                        return moduleSymbol;
+                    }
+                    var symbolFromVariable = void 0;
+                    // First check if module was specified with "export=". If so, get the member from the resolved type
+                    if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=")) {
+                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
+                    }
+                    else {
+                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
+                    }
+                    // if symbolFromVariable is export - get its final target
+                    symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
+                    var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
+                    // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
+                    if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") {
+                        symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
+                    }
+                    var symbol = symbolFromModule && symbolFromVariable ?
+                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
+                        symbolFromModule || symbolFromVariable;
+                    if (!symbol) {
+                        error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name));
+                    }
+                    return symbol;
+                }
+            }
+        }
+        function getTargetOfImportSpecifier(node, dontResolveAlias) {
+            return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
+        }
+        function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) {
+            return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
+        }
+        function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) {
+            return node.parent.parent.moduleSpecifier ?
+                getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
+                resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
+        }
+        function getTargetOfExportAssignment(node, dontResolveAlias) {
+            return resolveEntityName(node.expression, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
+        }
+        function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) {
+            switch (node.kind) {
+                case 237 /* ImportEqualsDeclaration */:
+                    return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve);
+                case 239 /* ImportClause */:
+                    return getTargetOfImportClause(node, dontRecursivelyResolve);
+                case 240 /* NamespaceImport */:
+                    return getTargetOfNamespaceImport(node, dontRecursivelyResolve);
+                case 242 /* ImportSpecifier */:
+                    return getTargetOfImportSpecifier(node, dontRecursivelyResolve);
+                case 246 /* ExportSpecifier */:
+                    return getTargetOfExportSpecifier(node, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve);
+                case 243 /* ExportAssignment */:
+                    return getTargetOfExportAssignment(node, dontRecursivelyResolve);
+                case 236 /* NamespaceExportDeclaration */:
+                    return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve);
+            }
+        }
+        /**
+         * Indicates that a symbol is an alias that does not merge with a local declaration.
+         */
+        function isNonLocalAlias(symbol, excludes) {
+            if (excludes === void 0) { excludes = 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */; }
+            return symbol && (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */;
+        }
+        function resolveSymbol(symbol, dontResolveAlias) {
+            var shouldResolve = !dontResolveAlias && isNonLocalAlias(symbol);
+            return shouldResolve ? resolveAlias(symbol) : symbol;
+        }
+        function resolveAlias(symbol) {
+            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
+            var links = getSymbolLinks(symbol);
+            if (!links.target) {
+                links.target = resolvingSymbol;
+                var node = getDeclarationOfAliasSymbol(symbol);
+                ts.Debug.assert(!!node);
+                var target = getTargetOfAliasDeclaration(node);
+                if (links.target === resolvingSymbol) {
+                    links.target = target || unknownSymbol;
+                }
+                else {
+                    error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
+                }
+            }
+            else if (links.target === resolvingSymbol) {
+                links.target = unknownSymbol;
+            }
+            return links.target;
+        }
+        function markExportAsReferenced(node) {
+            var symbol = getSymbolOfNode(node);
+            var target = resolveAlias(symbol);
+            if (target) {
+                var markAlias = target === unknownSymbol ||
+                    ((target.flags & 107455 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target));
+                if (markAlias) {
+                    markAliasSymbolAsReferenced(symbol);
+                }
+            }
+        }
+        // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
+        // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
+        // the alias as an expression (which recursively takes us back here if the target references another alias).
+        function markAliasSymbolAsReferenced(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.referenced) {
+                links.referenced = true;
+                var node = getDeclarationOfAliasSymbol(symbol);
+                ts.Debug.assert(!!node);
+                if (node.kind === 243 /* ExportAssignment */) {
+                    // export default <symbol>
+                    checkExpressionCached(node.expression);
+                }
+                else if (node.kind === 246 /* ExportSpecifier */) {
+                    // export { <symbol> } or export { <symbol> as foo }
+                    checkExpressionCached(node.propertyName || node.name);
+                }
+                else if (ts.isInternalModuleImportEqualsDeclaration(node)) {
+                    // import foo = <symbol>
+                    checkExpressionCached(node.moduleReference);
+                }
+            }
+        }
+        // This function is only for imports with entity names
+        function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) {
+            // There are three things we might try to look for. In the following examples,
+            // the search term is enclosed in |...|:
+            //
+            //     import a = |b|; // Namespace
+            //     import a = |b.c|; // Value, type, namespace
+            //     import a = |b.c|.d; // Namespace
+            if (entityName.kind === 71 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
+                entityName = entityName.parent;
+            }
+            // Check for case 1 and 3 in the above example
+            if (entityName.kind === 71 /* Identifier */ || entityName.parent.kind === 143 /* QualifiedName */) {
+                return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
+            }
+            else {
+                // Case 2 in above example
+                // entityName.kind could be a QualifiedName or a Missing identifier
+                ts.Debug.assert(entityName.parent.kind === 237 /* ImportEqualsDeclaration */);
+                return resolveEntityName(entityName, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
+            }
+        }
+        function getFullyQualifiedName(symbol) {
+            return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
+        }
+        /**
+         * Resolves a qualified name and any involved aliases.
+         */
+        function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) {
+            if (ts.nodeIsMissing(name)) {
+                return undefined;
+            }
+            var symbol;
+            if (name.kind === 71 /* Identifier */) {
+                var message = meaning === 1920 /* Namespace */ ? ts.Diagnostics.Cannot_find_namespace_0 : ts.Diagnostics.Cannot_find_name_0;
+                symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors ? undefined : message, name, /*isUse*/ true);
+                if (!symbol) {
+                    return undefined;
+                }
+            }
+            else if (name.kind === 143 /* QualifiedName */ || name.kind === 179 /* PropertyAccessExpression */) {
+                var left = void 0;
+                if (name.kind === 143 /* QualifiedName */) {
+                    left = name.left;
+                }
+                else if (name.kind === 179 /* PropertyAccessExpression */ &&
+                    (name.expression.kind === 185 /* ParenthesizedExpression */ || ts.isEntityNameExpression(name.expression))) {
+                    left = name.expression;
+                }
+                else {
+                    // If the expression in property-access expression is not entity-name or parenthsizedExpression (e.g. it is a call expression), it won't be able to successfully resolve the name.
+                    // This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression
+                    // will attempt to checkPropertyAccessExpression to resolve symbol.
+                    // i.e class C extends foo()./*do language service operation here*/B {}
+                    return undefined;
+                }
+                var right = name.kind === 143 /* QualifiedName */ ? name.right : name.name;
+                var namespace = resolveEntityName(left, 1920 /* Namespace */, ignoreErrors, /*dontResolveAlias*/ false, location);
+                if (!namespace || ts.nodeIsMissing(right)) {
+                    return undefined;
+                }
+                else if (namespace === unknownSymbol) {
+                    return namespace;
+                }
+                symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
+                if (!symbol) {
+                    if (!ignoreErrors) {
+                        error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
+                    }
+                    return undefined;
+                }
+            }
+            else if (name.kind === 185 /* ParenthesizedExpression */) {
+                // If the expression in parenthesizedExpression is not an entity-name (e.g. it is a call expression), it won't be able to successfully resolve the name.
+                // This is the case when we are trying to do any language service operation in heritage clauses.
+                // By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression will attempt to checkPropertyAccessExpression to resolve symbol.
+                // i.e class C extends foo()./*do language service operation here*/B {}
+                return ts.isEntityNameExpression(name.expression) ?
+                    resolveEntityName(name.expression, meaning, ignoreErrors, dontResolveAlias, location) :
+                    undefined;
+            }
+            else {
+                ts.Debug.assertNever(name, "Unknown entity name kind.");
+            }
+            ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
+            return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
+        }
+        function resolveExternalModuleName(location, moduleReferenceExpression) {
+            return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ts.Diagnostics.Cannot_find_module_0);
+        }
+        function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) {
+            if (isForAugmentation === void 0) { isForAugmentation = false; }
+            if (moduleReferenceExpression.kind !== 9 /* StringLiteral */ && moduleReferenceExpression.kind !== 13 /* NoSubstitutionTemplateLiteral */) {
+                return;
+            }
+            var moduleReferenceLiteral = moduleReferenceExpression;
+            return resolveExternalModule(location, moduleReferenceLiteral.text, moduleNotFoundError, moduleReferenceLiteral, isForAugmentation);
+        }
+        function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
+            if (isForAugmentation === void 0) { isForAugmentation = false; }
+            if (moduleReference === undefined) {
+                return;
+            }
+            if (ts.startsWith(moduleReference, "@types/")) {
+                var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
+                var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/");
+                error(errorNode, diag, withoutAtTypePrefix, moduleReference);
+            }
+            var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true);
+            if (ambientModule) {
+                return ambientModule;
+            }
+            var resolvedModule = ts.getResolvedModule(ts.getSourceFileOfNode(location), moduleReference);
+            var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule);
+            var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
+            if (sourceFile) {
+                if (sourceFile.symbol) {
+                    // merged symbol is module declaration symbol combined with all augmentations
+                    return getMergedSymbol(sourceFile.symbol);
+                }
+                if (moduleNotFoundError) {
+                    // report errors only if it was requested
+                    error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
+                }
+                return undefined;
+            }
+            if (patternAmbientModules) {
+                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference);
+                if (pattern) {
+                    return getMergedSymbol(pattern.symbol);
+                }
+            }
+            // May be an untyped module. If so, ignore resolutionDiagnostic.
+            if (resolvedModule && !ts.extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
+                if (isForAugmentation) {
+                    var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
+                    error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
+                }
+                else if (noImplicitAny && moduleNotFoundError) {
+                    var errorInfo = !resolvedModule.isExternalLibraryImport ? undefined : ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference);
+                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedModule.resolvedFileName);
+                    diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo));
+                }
+                // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
+                return undefined;
+            }
+            if (moduleNotFoundError) {
+                // report errors only if it was requested
+                if (resolutionDiagnostic) {
+                    error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
+                }
+                else {
+                    var tsExtension = ts.tryExtractTypeScriptExtension(moduleReference);
+                    if (tsExtension) {
+                        var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
+                        error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension));
+                    }
+                    else {
+                        error(errorNode, moduleNotFoundError, moduleReference);
+                    }
+                }
+            }
+            return undefined;
+        }
+        // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
+        // and an external module with no 'export =' declaration resolves to the module itself.
+        function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) {
+            return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias)) || moduleSymbol;
+        }
+        // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
+        // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
+        // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
+        function resolveESModuleSymbol(moduleSymbol, moduleReferenceExpression, dontResolveAlias) {
+            var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
+            if (!dontResolveAlias && symbol && !(symbol.flags & (1536 /* Module */ | 3 /* Variable */))) {
+                error(moduleReferenceExpression, ts.Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol));
+            }
+            return symbol;
+        }
+        function hasExportAssignmentSymbol(moduleSymbol) {
+            return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined;
+        }
+        function getExportsOfModuleAsArray(moduleSymbol) {
+            return symbolsToArray(getExportsOfModule(moduleSymbol));
+        }
+        function getExportsAndPropertiesOfModule(moduleSymbol) {
+            var exports = getExportsOfModuleAsArray(moduleSymbol);
+            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
+            if (exportEquals !== moduleSymbol) {
+                ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
+            }
+            return exports;
+        }
+        function tryGetMemberInModuleExports(memberName, moduleSymbol) {
+            var symbolTable = getExportsOfModule(moduleSymbol);
+            if (symbolTable) {
+                return symbolTable.get(memberName);
+            }
+        }
+        function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) {
+            var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
+            if (!symbol) {
+                var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
+                if (exportEquals !== moduleSymbol) {
+                    return getPropertyOfType(getTypeOfSymbol(exportEquals), memberName);
+                }
+            }
+            return symbol;
+        }
+        function getExportsOfSymbol(symbol) {
+            return symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) : symbol.exports || emptySymbols;
+        }
+        function getExportsOfModule(moduleSymbol) {
+            var links = getSymbolLinks(moduleSymbol);
+            return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
+        }
+        /**
+         * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
+         * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
+         */
+        function extendExportSymbols(target, source, lookupTable, exportNode) {
+            source && source.forEach(function (sourceSymbol, id) {
+                if (id === "default")
+                    return;
+                var targetSymbol = target.get(id);
+                if (!targetSymbol) {
+                    target.set(id, sourceSymbol);
+                    if (lookupTable && exportNode) {
+                        lookupTable.set(id, {
+                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
+                        });
+                    }
+                }
+                else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) {
+                    var collisionTracker = lookupTable.get(id);
+                    if (!collisionTracker.exportsWithDuplicate) {
+                        collisionTracker.exportsWithDuplicate = [exportNode];
+                    }
+                    else {
+                        collisionTracker.exportsWithDuplicate.push(exportNode);
+                    }
+                }
+            });
+        }
+        function getExportsOfModuleWorker(moduleSymbol) {
+            var visitedSymbols = [];
+            // A module defined by an 'export=' consists on one export that needs to be resolved
+            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
+            return visit(moduleSymbol) || emptySymbols;
+            // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
+            // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
+            function visit(symbol) {
+                if (!(symbol && symbol.flags & 1952 /* HasExports */ && ts.pushIfUnique(visitedSymbols, symbol))) {
+                    return;
+                }
+                var symbols = ts.cloneMap(symbol.exports);
+                // All export * declarations are collected in an __export symbol by the binder
+                var exportStars = symbol.exports.get("__export" /* ExportStar */);
+                if (exportStars) {
+                    var nestedSymbols = ts.createSymbolTable();
+                    var lookupTable_1 = ts.createMap();
+                    for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) {
+                        var node = _a[_i];
+                        var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
+                        var exportedSymbols = visit(resolvedModule);
+                        extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node);
+                    }
+                    lookupTable_1.forEach(function (_a, id) {
+                        var exportsWithDuplicate = _a.exportsWithDuplicate;
+                        // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
+                        if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) {
+                            return;
+                        }
+                        for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) {
+                            var node = exportsWithDuplicate_1[_i];
+                            diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id)));
+                        }
+                    });
+                    extendExportSymbols(symbols, nestedSymbols);
+                }
+                return symbols;
+            }
+        }
+        function getMergedSymbol(symbol) {
+            var merged;
+            return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
+        }
+        function getSymbolOfNode(node) {
+            return getMergedSymbol(node.symbol);
+        }
+        function getParentOfSymbol(symbol) {
+            return getMergedSymbol(symbol.parent);
+        }
+        function getExportSymbolOfValueSymbolIfExported(symbol) {
+            return symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0
+                ? getMergedSymbol(symbol.exportSymbol)
+                : symbol;
+        }
+        function symbolIsValue(symbol) {
+            return !!(symbol.flags & 107455 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 107455 /* Value */);
+        }
+        function findConstructorDeclaration(node) {
+            var members = node.members;
+            for (var _i = 0, members_2 = members; _i < members_2.length; _i++) {
+                var member = members_2[_i];
+                if (member.kind === 152 /* Constructor */ && ts.nodeIsPresent(member.body)) {
+                    return member;
+                }
+            }
+        }
+        function createType(flags) {
+            var result = new Type(checker, flags);
+            typeCount++;
+            result.id = typeCount;
+            return result;
+        }
+        function createIntrinsicType(kind, intrinsicName) {
+            var type = createType(kind);
+            type.intrinsicName = intrinsicName;
+            return type;
+        }
+        function createBooleanType(trueFalseTypes) {
+            var type = getUnionType(trueFalseTypes);
+            type.flags |= 8 /* Boolean */;
+            type.intrinsicName = "boolean";
+            return type;
+        }
+        function createObjectType(objectFlags, symbol) {
+            var type = createType(32768 /* Object */);
+            type.objectFlags = objectFlags;
+            type.symbol = symbol;
+            return type;
+        }
+        function createTypeofType() {
+            return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType));
+        }
+        // A reserved member name starts with two underscores, but the third character cannot be an underscore
+        // or the @ symbol. A third underscore indicates an escaped form of an identifer that started
+        // with at least two underscores. The @ character indicates that the name is denoted by a well known ES
+        // Symbol instance.
+        function isReservedMemberName(name) {
+            return name.charCodeAt(0) === 95 /* _ */ &&
+                name.charCodeAt(1) === 95 /* _ */ &&
+                name.charCodeAt(2) !== 95 /* _ */ &&
+                name.charCodeAt(2) !== 64 /* at */;
+        }
+        function getNamedMembers(members) {
+            var result;
+            members.forEach(function (symbol, id) {
+                if (!isReservedMemberName(id)) {
+                    if (!result)
+                        result = [];
+                    if (symbolIsValue(symbol)) {
+                        result.push(symbol);
+                    }
+                }
+            });
+            return result || ts.emptyArray;
+        }
+        function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
+            type.members = members;
+            type.properties = getNamedMembers(members);
+            type.callSignatures = callSignatures;
+            type.constructSignatures = constructSignatures;
+            if (stringIndexInfo)
+                type.stringIndexInfo = stringIndexInfo;
+            if (numberIndexInfo)
+                type.numberIndexInfo = numberIndexInfo;
+            return type;
+        }
+        function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
+            return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+        }
+        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
+            var result;
+            for (var location = enclosingDeclaration; location; location = location.parent) {
+                // Locals of a source file are not in scope (because they get merged into the global symbol table)
+                if (location.locals && !isGlobalSourceFile(location)) {
+                    if (result = callback(location.locals)) {
+                        return result;
+                    }
+                }
+                switch (location.kind) {
+                    case 265 /* SourceFile */:
+                        if (!ts.isExternalOrCommonJsModule(location)) {
+                            break;
+                        }
+                    // falls through
+                    case 233 /* ModuleDeclaration */:
+                        if (result = callback(getSymbolOfNode(location).exports)) {
+                            return result;
+                        }
+                        break;
+                }
+            }
+            return callback(globals);
+        }
+        function getQualifiedLeftMeaning(rightMeaning) {
+            // If we are looking in value space, the parent meaning is value, other wise it is namespace
+            return rightMeaning === 107455 /* Value */ ? 107455 /* Value */ : 1920 /* Namespace */;
+        }
+        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing) {
+            if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
+                return undefined;
+            }
+            var visitedSymbolTables = [];
+            return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
+            function getAccessibleSymbolChainFromSymbolTable(symbols) {
+                if (!ts.pushIfUnique(visitedSymbolTables, symbols)) {
+                    return undefined;
+                }
+                var result = trySymbolTable(symbols);
+                visitedSymbolTables.pop();
+                return result;
+            }
+            function canQualifySymbol(symbolFromSymbolTable, meaning) {
+                // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
+                return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
+                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
+                    !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
+            }
+            function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol) {
+                return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
+                    // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
+                    // and if symbolFromSymbolTable or alias resolution matches the symbol,
+                    // check the symbol can be qualified, it is only then this symbol is accessible
+                    !ts.some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
+                    canQualifySymbol(symbolFromSymbolTable, meaning);
+            }
+            function isUMDExportSymbol(symbol) {
+                return symbol && symbol.declarations && symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]);
+            }
+            function trySymbolTable(symbols) {
+                // If symbol is directly available by its name in the symbol table
+                if (isAccessible(symbols.get(symbol.escapedName))) {
+                    return [symbol];
+                }
+                // Check if symbol is any of the alias
+                return ts.forEachEntry(symbols, function (symbolFromSymbolTable) {
+                    if (symbolFromSymbolTable.flags & 2097152 /* Alias */
+                        && symbolFromSymbolTable.escapedName !== "export="
+                        && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)
+                        && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration)))
+                        // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
+                        && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))) {
+                        var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
+                        if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
+                            return [symbolFromSymbolTable];
+                        }
+                        // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
+                        // but only if the symbolFromSymbolTable can be qualified
+                        var accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTable(resolvedImportedSymbol.exports) : undefined;
+                        if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
+                            return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
+                        }
+                    }
+                });
+            }
+        }
+        function needsQualification(symbol, enclosingDeclaration, meaning) {
+            var qualify = false;
+            forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
+                // If symbol of this name is not available in the symbol table we are ok
+                var symbolFromSymbolTable = symbolTable.get(symbol.escapedName);
+                if (!symbolFromSymbolTable) {
+                    // Continue to the next symbol table
+                    return false;
+                }
+                // If the symbol with this name is present it should refer to the symbol
+                if (symbolFromSymbolTable === symbol) {
+                    // No need to qualify
+                    return true;
+                }
+                // Qualify if the symbol from symbol table has same meaning as expected
+                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable;
+                if (symbolFromSymbolTable.flags & meaning) {
+                    qualify = true;
+                    return true;
+                }
+                // Continue to the next symbol table
+                return false;
+            });
+            return qualify;
+        }
+        function isPropertyOrMethodDeclarationSymbol(symbol) {
+            if (symbol.declarations && symbol.declarations.length) {
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var declaration = _a[_i];
+                    switch (declaration.kind) {
+                        case 149 /* PropertyDeclaration */:
+                        case 151 /* MethodDeclaration */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                            continue;
+                        default:
+                            return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
+            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false);
+            return access.accessibility === 0 /* Accessible */;
+        }
+        /**
+         * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
+         *
+         * @param symbol a Symbol to check if accessible
+         * @param enclosingDeclaration a Node containing reference to the symbol
+         * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
+         * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
+         */
+        function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) {
+            if (symbol && enclosingDeclaration && !(symbol.flags & 262144 /* TypeParameter */)) {
+                var initialSymbol = symbol;
+                var meaningToLook = meaning;
+                while (symbol) {
+                    // Symbol is accessible if it by itself is accessible
+                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, /*useOnlyExternalAliasing*/ false);
+                    if (accessibleSymbolChain) {
+                        var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
+                        if (!hasAccessibleDeclarations) {
+                            return {
+                                accessibility: 1 /* NotAccessible */,
+                                errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
+                                errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, 1920 /* Namespace */) : undefined,
+                            };
+                        }
+                        return hasAccessibleDeclarations;
+                    }
+                    // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
+                    // It could be a qualified symbol and hence verify the path
+                    // e.g.:
+                    // module m {
+                    //     export class c {
+                    //     }
+                    // }
+                    // const x: typeof m.c
+                    // In the above example when we start with checking if typeof m.c symbol is accessible,
+                    // we are going to see if c can be accessed in scope directly.
+                    // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
+                    // It is accessible if the parent m is accessible because then m.c can be accessed through qualification
+                    meaningToLook = getQualifiedLeftMeaning(meaning);
+                    symbol = getParentOfSymbol(symbol);
+                }
+                // This could be a symbol that is not exported in the external module
+                // or it could be a symbol from different external module that is not aliased and hence cannot be named
+                var symbolExternalModule = ts.forEach(initialSymbol.declarations, getExternalModuleContainer);
+                if (symbolExternalModule) {
+                    var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
+                    if (symbolExternalModule !== enclosingExternalModule) {
+                        // name from different external module that is not visible
+                        return {
+                            accessibility: 2 /* CannotBeNamed */,
+                            errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
+                            errorModuleName: symbolToString(symbolExternalModule)
+                        };
+                    }
+                }
+                // Just a local name that is not accessible
+                return {
+                    accessibility: 1 /* NotAccessible */,
+                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
+                };
+            }
+            return { accessibility: 0 /* Accessible */ };
+            function getExternalModuleContainer(declaration) {
+                var node = ts.findAncestor(declaration, hasExternalModuleSymbol);
+                return node && getSymbolOfNode(node);
+            }
+        }
+        function hasExternalModuleSymbol(declaration) {
+            return ts.isAmbientModule(declaration) || (declaration.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
+        }
+        function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) {
+            var aliasesToMakeVisible;
+            if (ts.forEach(symbol.declarations, function (declaration) { return !getIsDeclarationVisible(declaration); })) {
+                return undefined;
+            }
+            return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
+            function getIsDeclarationVisible(declaration) {
+                if (!isDeclarationVisible(declaration)) {
+                    // Mark the unexported alias as visible if its parent is visible
+                    // because these kind of aliases can be used to name types in declaration file
+                    var anyImportSyntax = getAnyImportSyntax(declaration);
+                    if (anyImportSyntax &&
+                        !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export
+                        isDeclarationVisible(anyImportSyntax.parent)) {
+                        // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
+                        // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
+                        // since we will do the emitting later in trackSymbol.
+                        if (shouldComputeAliasToMakeVisible) {
+                            getNodeLinks(declaration).isVisible = true;
+                            aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, anyImportSyntax);
+                        }
+                        return true;
+                    }
+                    // Declaration is not visible
+                    return false;
+                }
+                return true;
+            }
+        }
+        function isEntityNameVisible(entityName, enclosingDeclaration) {
+            // get symbol of the first identifier of the entityName
+            var meaning;
+            if (entityName.parent.kind === 162 /* TypeQuery */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
+                // Typeof value
+                meaning = 107455 /* Value */ | 1048576 /* ExportValue */;
+            }
+            else if (entityName.kind === 143 /* QualifiedName */ || entityName.kind === 179 /* PropertyAccessExpression */ ||
+                entityName.parent.kind === 237 /* ImportEqualsDeclaration */) {
+                // Left identifier from type reference or TypeAlias
+                // Entity name of the import declaration
+                meaning = 1920 /* Namespace */;
+            }
+            else {
+                // Type Reference or TypeAlias entity = Identifier
+                meaning = 793064 /* Type */;
+            }
+            var firstIdentifier = getFirstIdentifier(entityName);
+            var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
+            // Verify if the symbol is accessible
+            return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
+                accessibility: 1 /* NotAccessible */,
+                errorSymbolName: ts.getTextOfNode(firstIdentifier),
+                errorNode: firstIdentifier
+            };
+        }
+        function writeKeyword(writer, kind) {
+            writer.writeKeyword(ts.tokenToString(kind));
+        }
+        function writePunctuation(writer, kind) {
+            writer.writePunctuation(ts.tokenToString(kind));
+        }
+        function writeSpace(writer) {
+            writer.writeSpace(" ");
+        }
+        function symbolToString(symbol, enclosingDeclaration, meaning) {
+            return ts.usingSingleLineStringWriter(function (writer) {
+                getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
+            });
+        }
+        function signatureToString(signature, enclosingDeclaration, flags, kind) {
+            return ts.usingSingleLineStringWriter(function (writer) {
+                getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind);
+            });
+        }
+        function typeToString(type, enclosingDeclaration, flags) {
+            var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName);
+            ts.Debug.assert(typeNode !== undefined, "should always get typenode");
+            var options = { removeComments: true };
+            var writer = ts.createTextWriter("");
+            var printer = ts.createPrinter(options);
+            var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
+            printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer);
+            var result = writer.getText();
+            var maxLength = compilerOptions.noErrorTruncation || flags & 8 /* NoTruncation */ ? undefined : 100;
+            if (maxLength && result.length >= maxLength) {
+                return result.substr(0, maxLength - "...".length) + "...";
+            }
+            return result;
+            function toNodeBuilderFlags(flags) {
+                var result = ts.NodeBuilderFlags.None;
+                if (!flags) {
+                    return result;
+                }
+                if (flags & 8 /* NoTruncation */) {
+                    result |= ts.NodeBuilderFlags.NoTruncation;
+                }
+                if (flags & 256 /* UseFullyQualifiedType */) {
+                    result |= ts.NodeBuilderFlags.UseFullyQualifiedType;
+                }
+                if (flags & 4096 /* SuppressAnyReturnType */) {
+                    result |= ts.NodeBuilderFlags.SuppressAnyReturnType;
+                }
+                if (flags & 1 /* WriteArrayAsGenericType */) {
+                    result |= ts.NodeBuilderFlags.WriteArrayAsGenericType;
+                }
+                if (flags & 64 /* WriteTypeArgumentsOfSignature */) {
+                    result |= ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature;
+                }
+                return result;
+            }
+        }
+        function createNodeBuilder() {
+            return {
+                typeToTypeNode: function (type, enclosingDeclaration, flags) {
+                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
+                    var resultingNode = typeToTypeNodeHelper(type, context);
+                    var result = context.encounteredError ? undefined : resultingNode;
+                    return result;
+                },
+                indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags) {
+                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
+                    var resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context);
+                    var result = context.encounteredError ? undefined : resultingNode;
+                    return result;
+                },
+                signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags) {
+                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
+                    var resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context);
+                    var result = context.encounteredError ? undefined : resultingNode;
+                    return result;
+                }
+            };
+            function createNodeBuilderContext(enclosingDeclaration, flags) {
+                return {
+                    enclosingDeclaration: enclosingDeclaration,
+                    flags: flags,
+                    encounteredError: false,
+                    symbolStack: undefined
+                };
+            }
+            function typeToTypeNodeHelper(type, context) {
+                var inTypeAlias = context.flags & ts.NodeBuilderFlags.InTypeAlias;
+                context.flags &= ~ts.NodeBuilderFlags.InTypeAlias;
+                if (!type) {
+                    context.encounteredError = true;
+                    return undefined;
+                }
+                if (type.flags & 1 /* Any */) {
+                    return ts.createKeywordTypeNode(119 /* AnyKeyword */);
+                }
+                if (type.flags & 2 /* String */) {
+                    return ts.createKeywordTypeNode(136 /* StringKeyword */);
+                }
+                if (type.flags & 4 /* Number */) {
+                    return ts.createKeywordTypeNode(133 /* NumberKeyword */);
+                }
+                if (type.flags & 8 /* Boolean */) {
+                    return ts.createKeywordTypeNode(122 /* BooleanKeyword */);
+                }
+                if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */)) {
+                    var parentSymbol = getParentOfSymbol(type.symbol);
+                    var parentName = symbolToName(parentSymbol, context, 793064 /* Type */, /*expectsIdentifier*/ false);
+                    var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : ts.createQualifiedName(parentName, getNameOfSymbol(type.symbol, context));
+                    return ts.createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
+                }
+                if (type.flags & 272 /* EnumLike */) {
+                    var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false);
+                    return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined);
+                }
+                if (type.flags & (32 /* StringLiteral */)) {
+                    return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value), 16777216 /* NoAsciiEscaping */));
+                }
+                if (type.flags & (64 /* NumberLiteral */)) {
+                    return ts.createLiteralTypeNode((ts.createLiteral(type.value)));
+                }
+                if (type.flags & 128 /* BooleanLiteral */) {
+                    return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse();
+                }
+                if (type.flags & 1024 /* Void */) {
+                    return ts.createKeywordTypeNode(105 /* VoidKeyword */);
+                }
+                if (type.flags & 2048 /* Undefined */) {
+                    return ts.createKeywordTypeNode(139 /* UndefinedKeyword */);
+                }
+                if (type.flags & 4096 /* Null */) {
+                    return ts.createKeywordTypeNode(95 /* NullKeyword */);
+                }
+                if (type.flags & 8192 /* Never */) {
+                    return ts.createKeywordTypeNode(130 /* NeverKeyword */);
+                }
+                if (type.flags & 512 /* ESSymbol */) {
+                    return ts.createKeywordTypeNode(137 /* SymbolKeyword */);
+                }
+                if (type.flags & 16777216 /* NonPrimitive */) {
+                    return ts.createKeywordTypeNode(134 /* ObjectKeyword */);
+                }
+                if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
+                    if (context.flags & ts.NodeBuilderFlags.InObjectTypeLiteral) {
+                        if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowThisInObjectLiteral)) {
+                            context.encounteredError = true;
+                        }
+                    }
+                    return ts.createThis();
+                }
+                var objectFlags = getObjectFlags(type);
+                if (objectFlags & 4 /* Reference */) {
+                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
+                    return typeReferenceToTypeNode(type);
+                }
+                if (type.flags & 16384 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) {
+                    var name = type.symbol ? symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?");
+                    // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
+                    return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined);
+                }
+                if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) {
+                    var name = symbolToTypeReferenceName(type.aliasSymbol);
+                    var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
+                    return ts.createTypeReferenceNode(name, typeArgumentNodes);
+                }
+                if (type.flags & (65536 /* Union */ | 131072 /* Intersection */)) {
+                    var types = type.flags & 65536 /* Union */ ? formatUnionTypes(type.types) : type.types;
+                    var typeNodes = mapToTypeNodes(types, context);
+                    if (typeNodes && typeNodes.length > 0) {
+                        var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 65536 /* Union */ ? 166 /* UnionType */ : 167 /* IntersectionType */, typeNodes);
+                        return unionOrIntersectionTypeNode;
+                    }
+                    else {
+                        if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowEmptyUnionOrIntersection)) {
+                            context.encounteredError = true;
+                        }
+                        return undefined;
+                    }
+                }
+                if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) {
+                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
+                    // The type is an object literal type.
+                    return createAnonymousTypeNode(type);
+                }
+                if (type.flags & 262144 /* Index */) {
+                    var indexedType = type.type;
+                    var indexTypeNode = typeToTypeNodeHelper(indexedType, context);
+                    return ts.createTypeOperatorNode(indexTypeNode);
+                }
+                if (type.flags & 524288 /* IndexedAccess */) {
+                    var objectTypeNode = typeToTypeNodeHelper(type.objectType, context);
+                    var indexTypeNode = typeToTypeNodeHelper(type.indexType, context);
+                    return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
+                }
+                ts.Debug.fail("Should be unreachable.");
+                function createMappedTypeNodeFromType(type) {
+                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
+                    var readonlyToken = type.declaration && type.declaration.readonlyToken ? ts.createToken(131 /* ReadonlyKeyword */) : undefined;
+                    var questionToken = type.declaration && type.declaration.questionToken ? ts.createToken(55 /* QuestionToken */) : undefined;
+                    var typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context);
+                    var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
+                    var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
+                    return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */);
+                }
+                function createAnonymousTypeNode(type) {
+                    var symbol = type.symbol;
+                    if (symbol) {
+                        // Always use 'typeof T' for type of class, enum, and module objects
+                        if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) ||
+                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) ||
+                            shouldWriteTypeOfFunctionSymbol()) {
+                            return createTypeQueryNodeFromSymbol(symbol, 107455 /* Value */);
+                        }
+                        else if (ts.contains(context.symbolStack, symbol)) {
+                            // If type is an anonymous type literal in a type alias declaration, use type alias name
+                            var typeAlias = getTypeAliasForTypeLiteral(type);
+                            if (typeAlias) {
+                                // The specified symbol flags need to be reinterpreted as type flags
+                                var entityName = symbolToName(typeAlias, context, 793064 /* Type */, /*expectsIdentifier*/ false);
+                                return ts.createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
+                            }
+                            else {
+                                return ts.createKeywordTypeNode(119 /* AnyKeyword */);
+                            }
+                        }
+                        else {
+                            // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
+                            // of types allows us to catch circular references to instantiations of the same anonymous type
+                            if (!context.symbolStack) {
+                                context.symbolStack = [];
+                            }
+                            context.symbolStack.push(symbol);
+                            var result = createTypeNodeFromObjectType(type);
+                            context.symbolStack.pop();
+                            return result;
+                        }
+                    }
+                    else {
+                        // Anonymous types without a symbol are never circular.
+                        return createTypeNodeFromObjectType(type);
+                    }
+                    function shouldWriteTypeOfFunctionSymbol() {
+                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
+                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
+                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
+                            (symbol.parent || // is exported function symbol
+                                ts.forEach(symbol.declarations, function (declaration) {
+                                    return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */;
+                                }));
+                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
+                            // typeof is allowed only for static/non local functions
+                            return ts.contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively
+                        }
+                    }
+                }
+                function createTypeNodeFromObjectType(type) {
+                    if (isGenericMappedType(type)) {
+                        return createMappedTypeNodeFromType(type);
+                    }
+                    var resolved = resolveStructuredTypeMembers(type);
+                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
+                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
+                            return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */);
+                        }
+                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
+                            var signature = resolved.callSignatures[0];
+                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 160 /* FunctionType */, context);
+                            return signatureNode;
+                        }
+                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
+                            var signature = resolved.constructSignatures[0];
+                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 161 /* ConstructorType */, context);
+                            return signatureNode;
+                        }
+                    }
+                    var savedFlags = context.flags;
+                    context.flags |= ts.NodeBuilderFlags.InObjectTypeLiteral;
+                    var members = createTypeNodesFromResolvedType(resolved);
+                    context.flags = savedFlags;
+                    var typeLiteralNode = ts.createTypeLiteralNode(members);
+                    return ts.setEmitFlags(typeLiteralNode, 1 /* SingleLine */);
+                }
+                function createTypeQueryNodeFromSymbol(symbol, symbolFlags) {
+                    var entityName = symbolToName(symbol, context, symbolFlags, /*expectsIdentifier*/ false);
+                    return ts.createTypeQueryNode(entityName);
+                }
+                function symbolToTypeReferenceName(symbol) {
+                    // Unnamed function expressions and arrow functions have reserved names that we don't want to display
+                    var entityName = symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName) ? symbolToName(symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("");
+                    return entityName;
+                }
+                function typeReferenceToTypeNode(type) {
+                    var typeArguments = type.typeArguments || ts.emptyArray;
+                    if (type.target === globalArrayType) {
+                        if (context.flags & ts.NodeBuilderFlags.WriteArrayAsGenericType) {
+                            var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
+                            return ts.createTypeReferenceNode("Array", [typeArgumentNode]);
+                        }
+                        var elementType = typeToTypeNodeHelper(typeArguments[0], context);
+                        return ts.createArrayTypeNode(elementType);
+                    }
+                    else if (type.target.objectFlags & 8 /* Tuple */) {
+                        if (typeArguments.length > 0) {
+                            var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, getTypeReferenceArity(type)), context);
+                            if (tupleConstituentNodes && tupleConstituentNodes.length > 0) {
+                                return ts.createTupleTypeNode(tupleConstituentNodes);
+                            }
+                        }
+                        if (context.encounteredError || (context.flags & ts.NodeBuilderFlags.AllowEmptyTuple)) {
+                            return ts.createTupleTypeNode([]);
+                        }
+                        context.encounteredError = true;
+                        return undefined;
+                    }
+                    else {
+                        var outerTypeParameters = type.target.outerTypeParameters;
+                        var i = 0;
+                        var qualifiedName = void 0;
+                        if (outerTypeParameters) {
+                            var length_1 = outerTypeParameters.length;
+                            while (i < length_1) {
+                                // Find group of type arguments for type parameters with the same declaring container.
+                                var start = i;
+                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
+                                do {
+                                    i++;
+                                } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
+                                // When type parameters are their own type arguments for the whole group (i.e. we have
+                                // the default outer type arguments), we don't show the group.
+                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
+                                    var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
+                                    var typeArgumentNodes_1 = typeArgumentSlice && ts.createNodeArray(typeArgumentSlice);
+                                    var namePart = symbolToTypeReferenceName(parent);
+                                    (namePart.kind === 71 /* Identifier */ ? namePart : namePart.right).typeArguments = typeArgumentNodes_1;
+                                    if (qualifiedName) {
+                                        ts.Debug.assert(!qualifiedName.right);
+                                        qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, namePart);
+                                        qualifiedName = ts.createQualifiedName(qualifiedName, /*right*/ undefined);
+                                    }
+                                    else {
+                                        qualifiedName = ts.createQualifiedName(namePart, /*right*/ undefined);
+                                    }
+                                }
+                            }
+                        }
+                        var entityName = undefined;
+                        var nameIdentifier = symbolToTypeReferenceName(type.symbol);
+                        if (qualifiedName) {
+                            ts.Debug.assert(!qualifiedName.right);
+                            qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, nameIdentifier);
+                            entityName = qualifiedName;
+                        }
+                        else {
+                            entityName = nameIdentifier;
+                        }
+                        var typeArgumentNodes = void 0;
+                        if (typeArguments.length > 0) {
+                            var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
+                            typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
+                        }
+                        if (typeArgumentNodes) {
+                            var lastIdentifier = entityName.kind === 71 /* Identifier */ ? entityName : entityName.right;
+                            lastIdentifier.typeArguments = undefined;
+                        }
+                        return ts.createTypeReferenceNode(entityName, typeArgumentNodes);
+                    }
+                }
+                function addToQualifiedNameMissingRightIdentifier(left, right) {
+                    ts.Debug.assert(left.right === undefined);
+                    if (right.kind === 71 /* Identifier */) {
+                        left.right = right;
+                        return left;
+                    }
+                    var rightPart = right;
+                    while (rightPart.left.kind !== 71 /* Identifier */) {
+                        rightPart = rightPart.left;
+                    }
+                    left.right = rightPart.left;
+                    rightPart.left = left;
+                    return right;
+                }
+                function createTypeNodesFromResolvedType(resolvedType) {
+                    var typeElements = [];
+                    for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) {
+                        var signature = _a[_i];
+                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 155 /* CallSignature */, context));
+                    }
+                    for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) {
+                        var signature = _c[_b];
+                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 156 /* ConstructSignature */, context));
+                    }
+                    if (resolvedType.stringIndexInfo) {
+                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context));
+                    }
+                    if (resolvedType.numberIndexInfo) {
+                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context));
+                    }
+                    var properties = resolvedType.properties;
+                    if (!properties) {
+                        return typeElements;
+                    }
+                    for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) {
+                        var propertySymbol = properties_1[_d];
+                        var propertyType = getTypeOfSymbol(propertySymbol);
+                        var saveEnclosingDeclaration = context.enclosingDeclaration;
+                        context.enclosingDeclaration = undefined;
+                        var propertyName = symbolToName(propertySymbol, context, 107455 /* Value */, /*expectsIdentifier*/ true);
+                        context.enclosingDeclaration = saveEnclosingDeclaration;
+                        var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(55 /* QuestionToken */) : undefined;
+                        if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length) {
+                            var signatures = getSignaturesOfType(propertyType, 0 /* Call */);
+                            for (var _e = 0, signatures_1 = signatures; _e < signatures_1.length; _e++) {
+                                var signature = signatures_1[_e];
+                                var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 150 /* MethodSignature */, context);
+                                methodDeclaration.name = propertyName;
+                                methodDeclaration.questionToken = optionalToken;
+                                typeElements.push(methodDeclaration);
+                            }
+                        }
+                        else {
+                            var propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : ts.createKeywordTypeNode(119 /* AnyKeyword */);
+                            var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined;
+                            var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, 
+                            /*initializer*/ undefined);
+                            typeElements.push(propertySignature);
+                        }
+                    }
+                    return typeElements.length ? typeElements : undefined;
+                }
+            }
+            function mapToTypeNodes(types, context) {
+                if (ts.some(types)) {
+                    var result = [];
+                    for (var i = 0; i < types.length; ++i) {
+                        var type = types[i];
+                        var typeNode = typeToTypeNodeHelper(type, context);
+                        if (typeNode) {
+                            result.push(typeNode);
+                        }
+                    }
+                    return result;
+                }
+            }
+            function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) {
+                var name = ts.getNameFromIndexInfo(indexInfo) || "x";
+                var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 136 /* StringKeyword */ : 133 /* NumberKeyword */);
+                var indexingParameter = ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, 
+                /*dotDotDotToken*/ undefined, name, 
+                /*questionToken*/ undefined, indexerTypeNode, 
+                /*initializer*/ undefined);
+                var typeNode = typeToTypeNodeHelper(indexInfo.type, context);
+                return ts.createIndexSignature(
+                /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode);
+            }
+            function signatureToSignatureDeclarationHelper(signature, kind, context) {
+                var typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); });
+                var parameters = signature.parameters.map(function (parameter) { return symbolToParameterDeclaration(parameter, context); });
+                if (signature.thisParameter) {
+                    var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
+                    parameters.unshift(thisParameter);
+                }
+                var returnTypeNode;
+                if (signature.typePredicate) {
+                    var typePredicate = signature.typePredicate;
+                    var parameterName = typePredicate.kind === 1 /* Identifier */ ?
+                        ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) :
+                        ts.createThisTypeNode();
+                    var typeNode = typeToTypeNodeHelper(typePredicate.type, context);
+                    returnTypeNode = ts.createTypePredicateNode(parameterName, typeNode);
+                }
+                else {
+                    var returnType = getReturnTypeOfSignature(signature);
+                    returnTypeNode = returnType && typeToTypeNodeHelper(returnType, context);
+                }
+                if (context.flags & ts.NodeBuilderFlags.SuppressAnyReturnType) {
+                    if (returnTypeNode && returnTypeNode.kind === 119 /* AnyKeyword */) {
+                        returnTypeNode = undefined;
+                    }
+                }
+                else if (!returnTypeNode) {
+                    returnTypeNode = ts.createKeywordTypeNode(119 /* AnyKeyword */);
+                }
+                return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode);
+            }
+            function typeParameterToDeclaration(type, context) {
+                var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ true);
+                var constraint = getConstraintFromTypeParameter(type);
+                var constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
+                var defaultParameter = getDefaultFromTypeParameter(type);
+                var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
+                return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
+            }
+            function symbolToParameterDeclaration(parameterSymbol, context) {
+                var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 146 /* Parameter */);
+                if (isTransientSymbol(parameterSymbol) && parameterSymbol.isRestParameter) {
+                    // special-case synthetic rest parameters in JS files
+                    return ts.createParameter(
+                    /*decorators*/ undefined, 
+                    /*modifiers*/ undefined, parameterSymbol.isRestParameter ? ts.createToken(24 /* DotDotDotToken */) : undefined, "args", 
+                    /*questionToken*/ undefined, typeToTypeNodeHelper(anyArrayType, context), 
+                    /*initializer*/ undefined);
+                }
+                var modifiers = parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(ts.getSynthesizedClone);
+                var dotDotDotToken = ts.isRestParameter(parameterDeclaration) ? ts.createToken(24 /* DotDotDotToken */) : undefined;
+                var name = parameterDeclaration.name ?
+                    parameterDeclaration.name.kind === 71 /* Identifier */ ?
+                        ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) :
+                        cloneBindingName(parameterDeclaration.name) :
+                    ts.symbolName(parameterSymbol);
+                var questionToken = isOptionalParameter(parameterDeclaration) ? ts.createToken(55 /* QuestionToken */) : undefined;
+                var parameterType = getTypeOfSymbol(parameterSymbol);
+                if (isRequiredInitializedParameter(parameterDeclaration)) {
+                    parameterType = getNullableType(parameterType, 2048 /* Undefined */);
+                }
+                var parameterTypeNode = typeToTypeNodeHelper(parameterType, context);
+                var parameterNode = ts.createParameter(
+                /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, 
+                /*initializer*/ undefined);
+                return parameterNode;
+                function cloneBindingName(node) {
+                    return elideInitializerAndSetEmitFlags(node);
+                    function elideInitializerAndSetEmitFlags(node) {
+                        var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags);
+                        var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited);
+                        if (clone.kind === 176 /* BindingElement */) {
+                            clone.initializer = undefined;
+                        }
+                        return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */);
+                    }
+                }
+            }
+            function symbolToName(symbol, context, meaning, expectsIdentifier) {
+                // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
+                var chain;
+                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
+                if (!isTypeParameter && (context.enclosingDeclaration || context.flags & ts.NodeBuilderFlags.UseFullyQualifiedType)) {
+                    chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true);
+                    ts.Debug.assert(chain && chain.length > 0);
+                }
+                else {
+                    chain = [symbol];
+                }
+                if (expectsIdentifier && chain.length !== 1
+                    && !context.encounteredError
+                    && !(context.flags & ts.NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) {
+                    context.encounteredError = true;
+                }
+                return createEntityNameFromSymbolChain(chain, chain.length - 1);
+                function createEntityNameFromSymbolChain(chain, index) {
+                    ts.Debug.assert(chain && 0 <= index && index < chain.length);
+                    var symbol = chain[index];
+                    var typeParameterNodes;
+                    if (context.flags & ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) {
+                        var parentSymbol = chain[index - 1];
+                        var typeParameters = void 0;
+                        if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
+                            typeParameters = getTypeParametersOfClassOrInterface(parentSymbol);
+                        }
+                        else {
+                            var targetSymbol = getTargetSymbol(parentSymbol);
+                            if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) {
+                                typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
+                            }
+                        }
+                        typeParameterNodes = mapToTypeNodes(typeParameters, context);
+                    }
+                    var symbolName = getNameOfSymbol(symbol, context);
+                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
+                    return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
+                }
+                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
+                function getSymbolChain(symbol, meaning, endOfChain) {
+                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
+                    var parentSymbol;
+                    if (!accessibleSymbolChain ||
+                        needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
+                        // Go up and add our parent.
+                        var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol);
+                        if (parent) {
+                            var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
+                            if (parentChain) {
+                                parentSymbol = parent;
+                                accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]);
+                            }
+                        }
+                    }
+                    if (accessibleSymbolChain) {
+                        return accessibleSymbolChain;
+                    }
+                    if (
+                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
+                    endOfChain ||
+                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
+                        !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) &&
+                            // If a parent symbol is an anonymous type, don't write it.
+                            !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
+                        return [symbol];
+                    }
+                }
+            }
+        }
+        function typePredicateToString(typePredicate, enclosingDeclaration, flags) {
+            return ts.usingSingleLineStringWriter(function (writer) {
+                getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags);
+            });
+        }
+        function formatUnionTypes(types) {
+            var result = [];
+            var flags = 0;
+            for (var i = 0; i < types.length; i++) {
+                var t = types[i];
+                flags |= t.flags;
+                if (!(t.flags & 6144 /* Nullable */)) {
+                    if (t.flags & (128 /* BooleanLiteral */ | 256 /* EnumLiteral */)) {
+                        var baseType = t.flags & 128 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t);
+                        if (baseType.flags & 65536 /* Union */) {
+                            var count = baseType.types.length;
+                            if (i + count <= types.length && types[i + count - 1] === baseType.types[count - 1]) {
+                                result.push(baseType);
+                                i += count - 1;
+                                continue;
+                            }
+                        }
+                    }
+                    result.push(t);
+                }
+            }
+            if (flags & 4096 /* Null */)
+                result.push(nullType);
+            if (flags & 2048 /* Undefined */)
+                result.push(undefinedType);
+            return result || types;
+        }
+        function visibilityToString(flags) {
+            if (flags === 8 /* Private */) {
+                return "private";
+            }
+            if (flags === 16 /* Protected */) {
+                return "protected";
+            }
+            return "public";
+        }
+        function getTypeAliasForTypeLiteral(type) {
+            if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
+                var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 168 /* ParenthesizedType */; });
+                if (node.kind === 231 /* TypeAliasDeclaration */) {
+                    return getSymbolOfNode(node);
+                }
+            }
+            return undefined;
+        }
+        function isTopLevelInExternalModuleAugmentation(node) {
+            return node && node.parent &&
+                node.parent.kind === 234 /* ModuleBlock */ &&
+                ts.isExternalModuleAugmentation(node.parent.parent);
+        }
+        function literalTypeToString(type) {
+            return type.flags & 32 /* StringLiteral */ ? '"' + ts.escapeString(type.value) + '"' : "" + type.value;
+        }
+        function getNameOfSymbol(symbol, context) {
+            if (symbol.declarations && symbol.declarations.length) {
+                var declaration = symbol.declarations[0];
+                var name = ts.getNameOfDeclaration(declaration);
+                if (name) {
+                    return ts.declarationNameToString(name);
+                }
+                if (declaration.parent && declaration.parent.kind === 226 /* VariableDeclaration */) {
+                    return ts.declarationNameToString(declaration.parent.name);
+                }
+                if (context && !context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier)) {
+                    context.encounteredError = true;
+                }
+                switch (declaration.kind) {
+                    case 199 /* ClassExpression */:
+                        return "(Anonymous class)";
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                        return "(Anonymous function)";
+                }
+            }
+            if (symbol.syntheticLiteralTypeOrigin) {
+                var stringValue = symbol.syntheticLiteralTypeOrigin.value;
+                if (!ts.isIdentifierText(stringValue, compilerOptions.target)) {
+                    return "\"" + ts.escapeString(stringValue, 34 /* doubleQuote */) + "\"";
+                }
+            }
+            return ts.symbolName(symbol);
+        }
+        function getSymbolDisplayBuilder() {
+            /**
+             * Writes only the name of the symbol out to the writer. Uses the original source text
+             * for the name of the symbol if it is available to match how the user wrote the name.
+             */
+            function appendSymbolNameOnly(symbol, writer) {
+                writer.writeSymbol(getNameOfSymbol(symbol), symbol);
+            }
+            /**
+             * Writes a property access or element access with the name of the symbol out to the writer.
+             * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name,
+             * ensuring that any names written with literals use element accesses.
+             */
+            function appendPropertyOrElementAccessForSymbol(symbol, writer) {
+                var symbolName = getNameOfSymbol(symbol);
+                var firstChar = symbolName.charCodeAt(0);
+                var needsElementAccess = !ts.isIdentifierStart(firstChar, languageVersion);
+                if (needsElementAccess) {
+                    writePunctuation(writer, 21 /* OpenBracketToken */);
+                    if (ts.isSingleOrDoubleQuote(firstChar)) {
+                        writer.writeStringLiteral(symbolName);
+                    }
+                    else {
+                        writer.writeSymbol(symbolName, symbol);
+                    }
+                    writePunctuation(writer, 22 /* CloseBracketToken */);
+                }
+                else {
+                    writePunctuation(writer, 23 /* DotToken */);
+                    writer.writeSymbol(symbolName, symbol);
+                }
+            }
+            /**
+             * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
+             * Meaning needs to be specified if the enclosing declaration is given
+             */
+            function buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags, typeFlags) {
+                var parentSymbol;
+                function appendParentTypeArgumentsAndSymbolName(symbol) {
+                    if (parentSymbol) {
+                        // Write type arguments of instantiated class/interface here
+                        if (flags & 1 /* WriteTypeParametersOrArguments */) {
+                            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
+                                var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol);
+                                buildDisplayForTypeArgumentsAndDelimiters(params, symbol.mapper, writer, enclosingDeclaration);
+                            }
+                            else {
+                                buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
+                            }
+                        }
+                        appendPropertyOrElementAccessForSymbol(symbol, writer);
+                    }
+                    else {
+                        appendSymbolNameOnly(symbol, writer);
+                    }
+                    parentSymbol = symbol;
+                }
+                // Let the writer know we just wrote out a symbol.  The declaration emitter writer uses
+                // this to determine if an import it has previously seen (and not written out) needs
+                // to be written to the file once the walk of the tree is complete.
+                //
+                // NOTE(cyrusn): This approach feels somewhat unfortunate.  A simple pass over the tree
+                // up front (for example, during checking) could determine if we need to emit the imports
+                // and we could then access that data during declaration emit.
+                writer.trackSymbol(symbol, enclosingDeclaration, meaning);
+                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
+                function walkSymbol(symbol, meaning, endOfChain) {
+                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & 2 /* UseOnlyExternalAliasing */));
+                    if (!accessibleSymbolChain ||
+                        needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
+                        // Go up and add our parent.
+                        var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol);
+                        if (parent) {
+                            walkSymbol(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
+                        }
+                    }
+                    if (accessibleSymbolChain) {
+                        for (var _i = 0, accessibleSymbolChain_1 = accessibleSymbolChain; _i < accessibleSymbolChain_1.length; _i++) {
+                            var accessibleSymbol = accessibleSymbolChain_1[_i];
+                            appendParentTypeArgumentsAndSymbolName(accessibleSymbol);
+                        }
+                    }
+                    else if (
+                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
+                    endOfChain ||
+                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
+                        !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) &&
+                            // If a parent symbol is an anonymous type, don't write it.
+                            !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
+                        appendParentTypeArgumentsAndSymbolName(symbol);
+                    }
+                }
+                // Get qualified name if the symbol is not a type parameter
+                // and there is an enclosing declaration or we specifically
+                // asked for it
+                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
+                var typeFormatFlag = 256 /* UseFullyQualifiedType */ & typeFlags;
+                if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) {
+                    walkSymbol(symbol, meaning, /*endOfChain*/ true);
+                }
+                else {
+                    appendParentTypeArgumentsAndSymbolName(symbol);
+                }
+            }
+            function buildTypeDisplay(type, writer, enclosingDeclaration, globalFlags, symbolStack) {
+                var globalFlagsToPass = globalFlags & (32 /* WriteOwnNameForAnyLike */ | 16384 /* WriteClassExpressionAsTypeLiteral */);
+                var inObjectTypeLiteral = false;
+                return writeType(type, globalFlags);
+                function writeType(type, flags) {
+                    var nextFlags = flags & ~1024 /* InTypeAlias */;
+                    // Write undefined/null type as any
+                    if (type.flags & 16793231 /* Intrinsic */) {
+                        // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving
+                        writer.writeKeyword(!(globalFlags & 32 /* WriteOwnNameForAnyLike */) && isTypeAny(type)
+                            ? "any"
+                            : type.intrinsicName);
+                    }
+                    else if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
+                        if (inObjectTypeLiteral) {
+                            writer.reportInaccessibleThisError();
+                        }
+                        writer.writeKeyword("this");
+                    }
+                    else if (getObjectFlags(type) & 4 /* Reference */) {
+                        writeTypeReference(type, nextFlags);
+                    }
+                    else if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */)) {
+                        var parent = getParentOfSymbol(type.symbol);
+                        buildSymbolDisplay(parent, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags);
+                        // In a literal enum type with a single member E { A }, E and E.A denote the
+                        // same type. We always display this type simply as E.
+                        if (getDeclaredTypeOfSymbol(parent) !== type) {
+                            writePunctuation(writer, 23 /* DotToken */);
+                            appendSymbolNameOnly(type.symbol, writer);
+                        }
+                    }
+                    else if (getObjectFlags(type) & 3 /* ClassOrInterface */ || type.flags & (272 /* EnumLike */ | 16384 /* TypeParameter */)) {
+                        // The specified symbol flags need to be reinterpreted as type flags
+                        buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags);
+                    }
+                    else if (!(flags & 1024 /* InTypeAlias */) && type.aliasSymbol &&
+                        ((flags & 65536 /* UseAliasDefinedOutsideCurrentScope */) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) {
+                        var typeArguments = type.aliasTypeArguments;
+                        writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags);
+                    }
+                    else if (type.flags & 196608 /* UnionOrIntersection */) {
+                        writeUnionOrIntersectionType(type, nextFlags);
+                    }
+                    else if (getObjectFlags(type) & (16 /* Anonymous */ | 32 /* Mapped */)) {
+                        writeAnonymousType(type, nextFlags);
+                    }
+                    else if (type.flags & 96 /* StringOrNumberLiteral */) {
+                        writer.writeStringLiteral(literalTypeToString(type));
+                    }
+                    else if (type.flags & 262144 /* Index */) {
+                        if (flags & 128 /* InElementType */) {
+                            writePunctuation(writer, 19 /* OpenParenToken */);
+                        }
+                        writer.writeKeyword("keyof");
+                        writeSpace(writer);
+                        writeType(type.type, 128 /* InElementType */);
+                        if (flags & 128 /* InElementType */) {
+                            writePunctuation(writer, 20 /* CloseParenToken */);
+                        }
+                    }
+                    else if (type.flags & 524288 /* IndexedAccess */) {
+                        writeType(type.objectType, 128 /* InElementType */);
+                        writePunctuation(writer, 21 /* OpenBracketToken */);
+                        writeType(type.indexType, 0 /* None */);
+                        writePunctuation(writer, 22 /* CloseBracketToken */);
+                    }
+                    else {
+                        // Should never get here
+                        // { ... }
+                        writePunctuation(writer, 17 /* OpenBraceToken */);
+                        writeSpace(writer);
+                        writePunctuation(writer, 24 /* DotDotDotToken */);
+                        writeSpace(writer);
+                        writePunctuation(writer, 18 /* CloseBraceToken */);
+                    }
+                }
+                function writeTypeList(types, delimiter) {
+                    for (var i = 0; i < types.length; i++) {
+                        if (i > 0) {
+                            if (delimiter !== 26 /* CommaToken */) {
+                                writeSpace(writer);
+                            }
+                            writePunctuation(writer, delimiter);
+                            writeSpace(writer);
+                        }
+                        writeType(types[i], delimiter === 26 /* CommaToken */ ? 0 /* None */ : 128 /* InElementType */);
+                    }
+                }
+                function writeSymbolTypeReference(symbol, typeArguments, pos, end, flags) {
+                    // Unnamed function expressions and arrow functions have reserved names that we don't want to display
+                    if (symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName)) {
+                        buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags);
+                    }
+                    if (pos < end) {
+                        writePunctuation(writer, 27 /* LessThanToken */);
+                        writeType(typeArguments[pos], 512 /* InFirstTypeArgument */);
+                        pos++;
+                        while (pos < end) {
+                            writePunctuation(writer, 26 /* CommaToken */);
+                            writeSpace(writer);
+                            writeType(typeArguments[pos], 0 /* None */);
+                            pos++;
+                        }
+                        writePunctuation(writer, 29 /* GreaterThanToken */);
+                    }
+                }
+                function writeTypeReference(type, flags) {
+                    var typeArguments = type.typeArguments || ts.emptyArray;
+                    if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) {
+                        writeType(typeArguments[0], 128 /* InElementType */ | 32768 /* InArrayType */);
+                        writePunctuation(writer, 21 /* OpenBracketToken */);
+                        writePunctuation(writer, 22 /* CloseBracketToken */);
+                    }
+                    else if (type.target.objectFlags & 8 /* Tuple */) {
+                        writePunctuation(writer, 21 /* OpenBracketToken */);
+                        writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), 26 /* CommaToken */);
+                        writePunctuation(writer, 22 /* CloseBracketToken */);
+                    }
+                    else if (flags & 16384 /* WriteClassExpressionAsTypeLiteral */ &&
+                        type.symbol.valueDeclaration &&
+                        type.symbol.valueDeclaration.kind === 199 /* ClassExpression */) {
+                        writeAnonymousType(type, flags);
+                    }
+                    else {
+                        // Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments
+                        // for outer type parameters, and f and g are the respective declaring containers of those
+                        // type parameters.
+                        var outerTypeParameters = type.target.outerTypeParameters;
+                        var i = 0;
+                        if (outerTypeParameters) {
+                            var length_2 = outerTypeParameters.length;
+                            while (i < length_2) {
+                                // Find group of type arguments for type parameters with the same declaring container.
+                                var start = i;
+                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
+                                do {
+                                    i++;
+                                } while (i < length_2 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
+                                // When type parameters are their own type arguments for the whole group (i.e. we have
+                                // the default outer type arguments), we don't show the group.
+                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
+                                    writeSymbolTypeReference(parent, typeArguments, start, i, flags);
+                                    writePunctuation(writer, 23 /* DotToken */);
+                                }
+                            }
+                        }
+                        var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
+                        writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags);
+                    }
+                }
+                function writeUnionOrIntersectionType(type, flags) {
+                    if (flags & 128 /* InElementType */) {
+                        writePunctuation(writer, 19 /* OpenParenToken */);
+                    }
+                    if (type.flags & 65536 /* Union */) {
+                        writeTypeList(formatUnionTypes(type.types), 49 /* BarToken */);
+                    }
+                    else {
+                        writeTypeList(type.types, 48 /* AmpersandToken */);
+                    }
+                    if (flags & 128 /* InElementType */) {
+                        writePunctuation(writer, 20 /* CloseParenToken */);
+                    }
+                }
+                function writeAnonymousType(type, flags) {
+                    var symbol = type.symbol;
+                    if (symbol) {
+                        // Always use 'typeof T' for type of class, enum, and module objects
+                        if (symbol.flags & 32 /* Class */ &&
+                            !getBaseTypeVariableOfClass(symbol) &&
+                            !(symbol.valueDeclaration.kind === 199 /* ClassExpression */ && flags & 16384 /* WriteClassExpressionAsTypeLiteral */) ||
+                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */)) {
+                            writeTypeOfSymbol(type, flags);
+                        }
+                        else if (shouldWriteTypeOfFunctionSymbol()) {
+                            writeTypeOfSymbol(type, flags);
+                        }
+                        else if (ts.contains(symbolStack, symbol)) {
+                            // If type is an anonymous type literal in a type alias declaration, use type alias name
+                            var typeAlias = getTypeAliasForTypeLiteral(type);
+                            if (typeAlias) {
+                                // The specified symbol flags need to be reinterpreted as type flags
+                                buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags);
+                            }
+                            else {
+                                // Recursive usage, use any
+                                writeKeyword(writer, 119 /* AnyKeyword */);
+                            }
+                        }
+                        else {
+                            // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
+                            // of types allows us to catch circular references to instantiations of the same anonymous type
+                            // However, in case of class expressions, we want to write both the static side and the instance side.
+                            // We skip adding the static side so that the instance side has a chance to be written
+                            // before checking for circular references.
+                            if (!symbolStack) {
+                                symbolStack = [];
+                            }
+                            var isConstructorObject = type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */;
+                            if (isConstructorObject) {
+                                writeLiteralType(type, flags);
+                            }
+                            else {
+                                symbolStack.push(symbol);
+                                writeLiteralType(type, flags);
+                                symbolStack.pop();
+                            }
+                        }
+                    }
+                    else {
+                        // Anonymous types with no symbol are never circular
+                        writeLiteralType(type, flags);
+                    }
+                    function shouldWriteTypeOfFunctionSymbol() {
+                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
+                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
+                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
+                            (symbol.parent || // is exported function symbol
+                                ts.some(symbol.declarations, function (declaration) {
+                                    return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */;
+                                }));
+                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
+                            // typeof is allowed only for static/non local functions
+                            return !!(flags & 4 /* UseTypeOfFunction */) || // use typeof if format flags specify it
+                                ts.contains(symbolStack, symbol); // it is type of the symbol uses itself recursively
+                        }
+                    }
+                }
+                function writeTypeOfSymbol(type, typeFormatFlags) {
+                    if (typeFormatFlags & 32768 /* InArrayType */) {
+                        writePunctuation(writer, 19 /* OpenParenToken */);
+                    }
+                    writeKeyword(writer, 103 /* TypeOfKeyword */);
+                    writeSpace(writer);
+                    buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 107455 /* Value */, 0 /* None */, typeFormatFlags);
+                    if (typeFormatFlags & 32768 /* InArrayType */) {
+                        writePunctuation(writer, 20 /* CloseParenToken */);
+                    }
+                }
+                function writePropertyWithModifiers(prop) {
+                    if (isReadonlySymbol(prop)) {
+                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
+                        writeSpace(writer);
+                    }
+                    buildSymbolDisplay(prop, writer);
+                    if (prop.flags & 16777216 /* Optional */) {
+                        writePunctuation(writer, 55 /* QuestionToken */);
+                    }
+                }
+                function shouldAddParenthesisAroundFunctionType(callSignature, flags) {
+                    if (flags & 128 /* InElementType */) {
+                        return true;
+                    }
+                    else if (flags & 512 /* InFirstTypeArgument */) {
+                        // Add parenthesis around function type for the first type argument to avoid ambiguity
+                        var typeParameters = callSignature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */) ?
+                            callSignature.target.typeParameters : callSignature.typeParameters;
+                        return typeParameters && typeParameters.length !== 0;
+                    }
+                    return false;
+                }
+                function writeLiteralType(type, flags) {
+                    if (isGenericMappedType(type)) {
+                        writeMappedType(type);
+                        return;
+                    }
+                    var resolved = resolveStructuredTypeMembers(type);
+                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
+                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
+                            writePunctuation(writer, 17 /* OpenBraceToken */);
+                            writePunctuation(writer, 18 /* CloseBraceToken */);
+                            return;
+                        }
+                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
+                            var parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags);
+                            if (parenthesizeSignature) {
+                                writePunctuation(writer, 19 /* OpenParenToken */);
+                            }
+                            buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
+                            if (parenthesizeSignature) {
+                                writePunctuation(writer, 20 /* CloseParenToken */);
+                            }
+                            return;
+                        }
+                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
+                            if (flags & 128 /* InElementType */) {
+                                writePunctuation(writer, 19 /* OpenParenToken */);
+                            }
+                            writeKeyword(writer, 94 /* NewKeyword */);
+                            writeSpace(writer);
+                            buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
+                            if (flags & 128 /* InElementType */) {
+                                writePunctuation(writer, 20 /* CloseParenToken */);
+                            }
+                            return;
+                        }
+                    }
+                    var saveInObjectTypeLiteral = inObjectTypeLiteral;
+                    inObjectTypeLiteral = true;
+                    writePunctuation(writer, 17 /* OpenBraceToken */);
+                    writer.writeLine();
+                    writer.increaseIndent();
+                    writeObjectLiteralType(resolved);
+                    writer.decreaseIndent();
+                    writePunctuation(writer, 18 /* CloseBraceToken */);
+                    inObjectTypeLiteral = saveInObjectTypeLiteral;
+                }
+                function writeObjectLiteralType(resolved) {
+                    for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
+                        var signature = _a[_i];
+                        buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
+                        writePunctuation(writer, 25 /* SemicolonToken */);
+                        writer.writeLine();
+                    }
+                    for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
+                        var signature = _c[_b];
+                        buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, 1 /* Construct */, symbolStack);
+                        writePunctuation(writer, 25 /* SemicolonToken */);
+                        writer.writeLine();
+                    }
+                    buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, 0 /* String */, enclosingDeclaration, globalFlags, symbolStack);
+                    buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, 1 /* Number */, enclosingDeclaration, globalFlags, symbolStack);
+                    for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
+                        var p = _e[_d];
+                        if (globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */) {
+                            if (p.flags & 4194304 /* Prototype */) {
+                                continue;
+                            }
+                            if (ts.getDeclarationModifierFlagsFromSymbol(p) & (8 /* Private */ | 16 /* Protected */)) {
+                                writer.reportPrivateInBaseOfClassExpression(ts.symbolName(p));
+                            }
+                        }
+                        var t = getTypeOfSymbol(p);
+                        if (p.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(t).length) {
+                            var signatures = getSignaturesOfType(t, 0 /* Call */);
+                            for (var _f = 0, signatures_2 = signatures; _f < signatures_2.length; _f++) {
+                                var signature = signatures_2[_f];
+                                writePropertyWithModifiers(p);
+                                buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
+                                writePunctuation(writer, 25 /* SemicolonToken */);
+                                writer.writeLine();
+                            }
+                        }
+                        else {
+                            writePropertyWithModifiers(p);
+                            writePunctuation(writer, 56 /* ColonToken */);
+                            writeSpace(writer);
+                            writeType(t, globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */);
+                            writePunctuation(writer, 25 /* SemicolonToken */);
+                            writer.writeLine();
+                        }
+                    }
+                }
+                function writeMappedType(type) {
+                    writePunctuation(writer, 17 /* OpenBraceToken */);
+                    writer.writeLine();
+                    writer.increaseIndent();
+                    if (type.declaration.readonlyToken) {
+                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
+                        writeSpace(writer);
+                    }
+                    writePunctuation(writer, 21 /* OpenBracketToken */);
+                    appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer);
+                    writeSpace(writer);
+                    writeKeyword(writer, 92 /* InKeyword */);
+                    writeSpace(writer);
+                    writeType(getConstraintTypeFromMappedType(type), 0 /* None */);
+                    writePunctuation(writer, 22 /* CloseBracketToken */);
+                    if (type.declaration.questionToken) {
+                        writePunctuation(writer, 55 /* QuestionToken */);
+                    }
+                    writePunctuation(writer, 56 /* ColonToken */);
+                    writeSpace(writer);
+                    writeType(getTemplateTypeFromMappedType(type), 0 /* None */);
+                    writePunctuation(writer, 25 /* SemicolonToken */);
+                    writer.writeLine();
+                    writer.decreaseIndent();
+                    writePunctuation(writer, 18 /* CloseBraceToken */);
+                }
+            }
+            function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration, flags) {
+                var targetSymbol = getTargetSymbol(symbol);
+                if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) {
+                    buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaration, flags);
+                }
+            }
+            function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, symbolStack) {
+                appendSymbolNameOnly(tp.symbol, writer);
+                var constraint = getConstraintOfTypeParameter(tp);
+                if (constraint) {
+                    writeSpace(writer);
+                    writeKeyword(writer, 85 /* ExtendsKeyword */);
+                    writeSpace(writer);
+                    buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                var defaultType = getDefaultFromTypeParameter(tp);
+                if (defaultType) {
+                    writeSpace(writer);
+                    writePunctuation(writer, 58 /* EqualsToken */);
+                    writeSpace(writer);
+                    buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack);
+                }
+            }
+            function buildParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack) {
+                var parameterNode = p.valueDeclaration;
+                if (parameterNode ? ts.isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) {
+                    writePunctuation(writer, 24 /* DotDotDotToken */);
+                }
+                if (parameterNode && ts.isBindingPattern(parameterNode.name)) {
+                    buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                else {
+                    appendSymbolNameOnly(p, writer);
+                }
+                if (parameterNode && isOptionalParameter(parameterNode)) {
+                    writePunctuation(writer, 55 /* QuestionToken */);
+                }
+                writePunctuation(writer, 56 /* ColonToken */);
+                writeSpace(writer);
+                var type = getTypeOfSymbol(p);
+                if (parameterNode && isRequiredInitializedParameter(parameterNode)) {
+                    type = getNullableType(type, 2048 /* Undefined */);
+                }
+                buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
+            }
+            function buildBindingPatternDisplay(bindingPattern, writer, enclosingDeclaration, flags, symbolStack) {
+                // We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node.
+                if (bindingPattern.kind === 174 /* ObjectBindingPattern */) {
+                    writePunctuation(writer, 17 /* OpenBraceToken */);
+                    buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
+                    writePunctuation(writer, 18 /* CloseBraceToken */);
+                }
+                else if (bindingPattern.kind === 175 /* ArrayBindingPattern */) {
+                    writePunctuation(writer, 21 /* OpenBracketToken */);
+                    var elements = bindingPattern.elements;
+                    buildDisplayForCommaSeparatedList(elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
+                    if (elements && elements.hasTrailingComma) {
+                        writePunctuation(writer, 26 /* CommaToken */);
+                    }
+                    writePunctuation(writer, 22 /* CloseBracketToken */);
+                }
+            }
+            function buildBindingElementDisplay(bindingElement, writer, enclosingDeclaration, flags, symbolStack) {
+                if (ts.isOmittedExpression(bindingElement)) {
+                    return;
+                }
+                ts.Debug.assert(bindingElement.kind === 176 /* BindingElement */);
+                if (bindingElement.propertyName) {
+                    writer.writeProperty(ts.getTextOfNode(bindingElement.propertyName));
+                    writePunctuation(writer, 56 /* ColonToken */);
+                    writeSpace(writer);
+                }
+                if (ts.isBindingPattern(bindingElement.name)) {
+                    buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                else {
+                    if (bindingElement.dotDotDotToken) {
+                        writePunctuation(writer, 24 /* DotDotDotToken */);
+                    }
+                    appendSymbolNameOnly(bindingElement.symbol, writer);
+                }
+            }
+            function buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, flags, symbolStack) {
+                if (typeParameters && typeParameters.length) {
+                    writePunctuation(writer, 27 /* LessThanToken */);
+                    buildDisplayForCommaSeparatedList(typeParameters, writer, function (p) { return buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack); });
+                    writePunctuation(writer, 29 /* GreaterThanToken */);
+                }
+            }
+            function buildDisplayForCommaSeparatedList(list, writer, action) {
+                for (var i = 0; i < list.length; i++) {
+                    if (i > 0) {
+                        writePunctuation(writer, 26 /* CommaToken */);
+                        writeSpace(writer);
+                    }
+                    action(list[i]);
+                }
+            }
+            function buildDisplayForTypeArgumentsAndDelimiters(typeParameters, mapper, writer, enclosingDeclaration) {
+                if (typeParameters && typeParameters.length) {
+                    writePunctuation(writer, 27 /* LessThanToken */);
+                    var flags = 512 /* InFirstTypeArgument */;
+                    for (var i = 0; i < typeParameters.length; i++) {
+                        if (i > 0) {
+                            writePunctuation(writer, 26 /* CommaToken */);
+                            writeSpace(writer);
+                            flags = 0 /* None */;
+                        }
+                        buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags);
+                    }
+                    writePunctuation(writer, 29 /* GreaterThanToken */);
+                }
+            }
+            function buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosingDeclaration, flags, symbolStack) {
+                writePunctuation(writer, 19 /* OpenParenToken */);
+                if (thisParameter) {
+                    buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                for (var i = 0; i < parameters.length; i++) {
+                    if (i > 0 || thisParameter) {
+                        writePunctuation(writer, 26 /* CommaToken */);
+                        writeSpace(writer);
+                    }
+                    buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack);
+                }
+                writePunctuation(writer, 20 /* CloseParenToken */);
+            }
+            function buildTypePredicateDisplay(predicate, writer, enclosingDeclaration, flags, symbolStack) {
+                if (ts.isIdentifierTypePredicate(predicate)) {
+                    writer.writeParameter(predicate.parameterName);
+                }
+                else {
+                    writeKeyword(writer, 99 /* ThisKeyword */);
+                }
+                writeSpace(writer);
+                writeKeyword(writer, 126 /* IsKeyword */);
+                writeSpace(writer);
+                buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack);
+            }
+            function buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack) {
+                var returnType = getReturnTypeOfSignature(signature);
+                if (flags & 4096 /* SuppressAnyReturnType */ && isTypeAny(returnType)) {
+                    return;
+                }
+                if (flags & 16 /* WriteArrowStyleSignature */) {
+                    writeSpace(writer);
+                    writePunctuation(writer, 36 /* EqualsGreaterThanToken */);
+                }
+                else {
+                    writePunctuation(writer, 56 /* ColonToken */);
+                }
+                writeSpace(writer);
+                if (signature.typePredicate) {
+                    buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                else {
+                    buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
+                }
+            }
+            function buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind, symbolStack) {
+                if (kind === 1 /* Construct */) {
+                    writeKeyword(writer, 94 /* NewKeyword */);
+                    writeSpace(writer);
+                }
+                if (signature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */)) {
+                    // Instantiated signature, write type arguments instead
+                    // This is achieved by passing in the mapper separately
+                    buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration);
+                }
+                else {
+                    buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack);
+                }
+                buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack);
+                buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack);
+            }
+            function buildIndexSignatureDisplay(info, writer, kind, enclosingDeclaration, globalFlags, symbolStack) {
+                if (info) {
+                    if (info.isReadonly) {
+                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
+                        writeSpace(writer);
+                    }
+                    writePunctuation(writer, 21 /* OpenBracketToken */);
+                    writer.writeParameter(info.declaration ? ts.declarationNameToString(info.declaration.parameters[0].name) : "x");
+                    writePunctuation(writer, 56 /* ColonToken */);
+                    writeSpace(writer);
+                    switch (kind) {
+                        case 1 /* Number */:
+                            writeKeyword(writer, 133 /* NumberKeyword */);
+                            break;
+                        case 0 /* String */:
+                            writeKeyword(writer, 136 /* StringKeyword */);
+                            break;
+                    }
+                    writePunctuation(writer, 22 /* CloseBracketToken */);
+                    writePunctuation(writer, 56 /* ColonToken */);
+                    writeSpace(writer);
+                    buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack);
+                    writePunctuation(writer, 25 /* SemicolonToken */);
+                    writer.writeLine();
+                }
+            }
+            return _displayBuilder || (_displayBuilder = {
+                buildSymbolDisplay: buildSymbolDisplay,
+                buildTypeDisplay: buildTypeDisplay,
+                buildTypeParameterDisplay: buildTypeParameterDisplay,
+                buildTypePredicateDisplay: buildTypePredicateDisplay,
+                buildParameterDisplay: buildParameterDisplay,
+                buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
+                buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
+                buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
+                buildSignatureDisplay: buildSignatureDisplay,
+                buildIndexSignatureDisplay: buildIndexSignatureDisplay,
+                buildReturnTypeDisplay: buildReturnTypeDisplay
+            });
+        }
+        function isDeclarationVisible(node) {
+            if (node) {
+                var links = getNodeLinks(node);
+                if (links.isVisible === undefined) {
+                    links.isVisible = !!determineIfDeclarationIsVisible();
+                }
+                return links.isVisible;
+            }
+            return false;
+            function determineIfDeclarationIsVisible() {
+                switch (node.kind) {
+                    case 176 /* BindingElement */:
+                        return isDeclarationVisible(node.parent.parent);
+                    case 226 /* VariableDeclaration */:
+                        if (ts.isBindingPattern(node.name) &&
+                            !node.name.elements.length) {
+                            // If the binding pattern is empty, this variable declaration is not visible
+                            return false;
+                        }
+                    // falls through
+                    case 233 /* ModuleDeclaration */:
+                    case 229 /* ClassDeclaration */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 228 /* FunctionDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 237 /* ImportEqualsDeclaration */:
+                        // external module augmentation is always visible
+                        if (ts.isExternalModuleAugmentation(node)) {
+                            return true;
+                        }
+                        var parent = getDeclarationContainer(node);
+                        // If the node is not exported or it is not ambient module element (except import declaration)
+                        if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) &&
+                            !(node.kind !== 237 /* ImportEqualsDeclaration */ && parent.kind !== 265 /* SourceFile */ && ts.isInAmbientContext(parent))) {
+                            return isGlobalSourceFile(parent);
+                        }
+                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
+                        return isDeclarationVisible(parent);
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) {
+                            // Private/protected properties/methods are not visible
+                            return false;
+                        }
+                    // Public properties/methods are visible if its parents are visible, so:
+                    // falls through
+                    case 152 /* Constructor */:
+                    case 156 /* ConstructSignature */:
+                    case 155 /* CallSignature */:
+                    case 157 /* IndexSignature */:
+                    case 146 /* Parameter */:
+                    case 234 /* ModuleBlock */:
+                    case 160 /* FunctionType */:
+                    case 161 /* ConstructorType */:
+                    case 163 /* TypeLiteral */:
+                    case 159 /* TypeReference */:
+                    case 164 /* ArrayType */:
+                    case 165 /* TupleType */:
+                    case 166 /* UnionType */:
+                    case 167 /* IntersectionType */:
+                    case 168 /* ParenthesizedType */:
+                        return isDeclarationVisible(node.parent);
+                    // Default binding, import specifier and namespace import is visible
+                    // only on demand so by default it is not visible
+                    case 239 /* ImportClause */:
+                    case 240 /* NamespaceImport */:
+                    case 242 /* ImportSpecifier */:
+                        return false;
+                    // Type parameters are always visible
+                    case 145 /* TypeParameter */:
+                    // Source file and namespace export are always visible
+                    case 265 /* SourceFile */:
+                    case 236 /* NamespaceExportDeclaration */:
+                        return true;
+                    // Export assignments do not create name bindings outside the module
+                    case 243 /* ExportAssignment */:
+                        return false;
+                    default:
+                        return false;
+                }
+            }
+        }
+        function collectLinkedAliases(node) {
+            var exportSymbol;
+            if (node.parent && node.parent.kind === 243 /* ExportAssignment */) {
+                exportSymbol = resolveName(node.parent, node.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, ts.Diagnostics.Cannot_find_name_0, node, /*isUse*/ false);
+            }
+            else if (node.parent.kind === 246 /* ExportSpecifier */) {
+                exportSymbol = getTargetOfExportSpecifier(node.parent, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
+            }
+            var result = [];
+            if (exportSymbol) {
+                buildVisibleNodeList(exportSymbol.declarations);
+            }
+            return result;
+            function buildVisibleNodeList(declarations) {
+                ts.forEach(declarations, function (declaration) {
+                    getNodeLinks(declaration).isVisible = true;
+                    var resultNode = getAnyImportSyntax(declaration) || declaration;
+                    ts.pushIfUnique(result, resultNode);
+                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
+                        // Add the referenced top container visible
+                        var internalModuleReference = declaration.moduleReference;
+                        var firstIdentifier = getFirstIdentifier(internalModuleReference);
+                        var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false);
+                        if (importSymbol) {
+                            buildVisibleNodeList(importSymbol.declarations);
+                        }
+                    }
+                });
+            }
+        }
+        /**
+         * Push an entry on the type resolution stack. If an entry with the given target and the given property name
+         * is already on the stack, and no entries in between already have a type, then a circularity has occurred.
+         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
+         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
+         * In order to see if the same query has already been done before, the target object and the propertyName both
+         * must match the one passed in.
+         *
+         * @param target The symbol, type, or signature whose type is being queried
+         * @param propertyName The property name that should be used to query the target for its type
+         */
+        function pushTypeResolution(target, propertyName) {
+            var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
+            if (resolutionCycleStartIndex >= 0) {
+                // A cycle was found
+                var length_3 = resolutionTargets.length;
+                for (var i = resolutionCycleStartIndex; i < length_3; i++) {
+                    resolutionResults[i] = false;
+                }
+                return false;
+            }
+            resolutionTargets.push(target);
+            resolutionResults.push(/*items*/ true);
+            resolutionPropertyNames.push(propertyName);
+            return true;
+        }
+        function findResolutionCycleStartIndex(target, propertyName) {
+            for (var i = resolutionTargets.length - 1; i >= 0; i--) {
+                if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
+                    return -1;
+                }
+                if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+        function hasType(target, propertyName) {
+            if (propertyName === 0 /* Type */) {
+                return getSymbolLinks(target).type;
+            }
+            if (propertyName === 2 /* DeclaredType */) {
+                return getSymbolLinks(target).declaredType;
+            }
+            if (propertyName === 1 /* ResolvedBaseConstructorType */) {
+                return target.resolvedBaseConstructorType;
+            }
+            if (propertyName === 3 /* ResolvedReturnType */) {
+                return target.resolvedReturnType;
+            }
+            ts.Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
+        }
+        // Pop an entry from the type resolution stack and return its associated result value. The result value will
+        // be true if no circularities were detected, or false if a circularity was found.
+        function popTypeResolution() {
+            resolutionTargets.pop();
+            resolutionPropertyNames.pop();
+            return resolutionResults.pop();
+        }
+        function getDeclarationContainer(node) {
+            node = ts.findAncestor(ts.getRootDeclaration(node), function (node) {
+                switch (node.kind) {
+                    case 226 /* VariableDeclaration */:
+                    case 227 /* VariableDeclarationList */:
+                    case 242 /* ImportSpecifier */:
+                    case 241 /* NamedImports */:
+                    case 240 /* NamespaceImport */:
+                    case 239 /* ImportClause */:
+                        return false;
+                    default:
+                        return true;
+                }
+            });
+            return node && node.parent;
+        }
+        function getTypeOfPrototypeProperty(prototype) {
+            // TypeScript 1.0 spec (April 2014): 8.4
+            // Every class automatically contains a static property member named 'prototype',
+            // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
+            // It is an error to explicitly declare a static property member with the name 'prototype'.
+            var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype));
+            return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
+        }
+        // Return the type of the given property in the given type, or undefined if no such property exists
+        function getTypeOfPropertyOfType(type, name) {
+            var prop = getPropertyOfType(type, name);
+            return prop ? getTypeOfSymbol(prop) : undefined;
+        }
+        function isTypeAny(type) {
+            return type && (type.flags & 1 /* Any */) !== 0;
+        }
+        // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
+        // assigned by contextual typing.
+        function getTypeForBindingElementParent(node) {
+            var symbol = getSymbolOfNode(node);
+            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
+        }
+        function isComputedNonLiteralName(name) {
+            return name.kind === 144 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression);
+        }
+        function getRestType(source, properties, symbol) {
+            source = filterType(source, function (t) { return !(t.flags & 6144 /* Nullable */); });
+            if (source.flags & 8192 /* Never */) {
+                return emptyObjectType;
+            }
+            if (source.flags & 65536 /* Union */) {
+                return mapType(source, function (t) { return getRestType(t, properties, symbol); });
+            }
+            var members = ts.createSymbolTable();
+            var names = ts.createUnderscoreEscapedMap();
+            for (var _i = 0, properties_2 = properties; _i < properties_2.length; _i++) {
+                var name = properties_2[_i];
+                names.set(ts.getTextOfPropertyName(name), true);
+            }
+            for (var _a = 0, _b = getPropertiesOfType(source); _a < _b.length; _a++) {
+                var prop = _b[_a];
+                var inNamesToRemove = names.has(prop.escapedName);
+                var isPrivate = ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */);
+                var isSetOnlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
+                if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
+                    members.set(prop.escapedName, prop);
+                }
+            }
+            var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */);
+            var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */);
+            return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
+        }
+        /** Return the inferred type for a binding element */
+        function getTypeForBindingElement(declaration) {
+            var pattern = declaration.parent;
+            var parentType = getTypeForBindingElementParent(pattern.parent);
+            // If parent has the unknown (error) type, then so does this binding element
+            if (parentType === unknownType) {
+                return unknownType;
+            }
+            // If no type was specified or inferred for parent,
+            // infer from the initializer of the binding element if one is present.
+            // Otherwise, go with the undefined type of the parent.
+            if (!parentType) {
+                return declaration.initializer ? checkDeclarationInitializer(declaration) : parentType;
+            }
+            if (isTypeAny(parentType)) {
+                return parentType;
+            }
+            var type;
+            if (pattern.kind === 174 /* ObjectBindingPattern */) {
+                if (declaration.dotDotDotToken) {
+                    if (!isValidSpreadType(parentType)) {
+                        error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types);
+                        return unknownType;
+                    }
+                    var literalMembers = [];
+                    for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
+                        var element = _a[_i];
+                        if (!element.dotDotDotToken) {
+                            literalMembers.push(element.propertyName || element.name);
+                        }
+                    }
+                    type = getRestType(parentType, literalMembers, declaration.symbol);
+                }
+                else {
+                    // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
+                    var name = declaration.propertyName || declaration.name;
+                    if (isComputedNonLiteralName(name)) {
+                        // computed properties with non-literal names are treated as 'any'
+                        return anyType;
+                    }
+                    // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
+                    // or otherwise the type of the string index signature.
+                    var text = ts.getTextOfPropertyName(name);
+                    var declaredType = getTypeOfPropertyOfType(parentType, text);
+                    type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
+                        isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
+                        getIndexTypeOfType(parentType, 0 /* String */);
+                    if (!type) {
+                        error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name));
+                        return unknownType;
+                    }
+                }
+            }
+            else {
+                // This elementType will be used if the specific property corresponding to this index is not
+                // present (aka the tuple element property). This call also checks that the parentType is in
+                // fact an iterable or array (depending on target language).
+                var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
+                if (declaration.dotDotDotToken) {
+                    // Rest element has an array type with the same element type as the parent type
+                    type = createArrayType(elementType);
+                }
+                else {
+                    // Use specific property type when parent is a tuple or numeric index type when parent is an array
+                    var propName = "" + ts.indexOf(pattern.elements, declaration);
+                    type = isTupleLikeType(parentType)
+                        ? getTypeOfPropertyOfType(parentType, propName)
+                        : elementType;
+                    if (!type) {
+                        if (isTupleType(parentType)) {
+                            error(declaration, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length);
+                        }
+                        else {
+                            error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
+                        }
+                        return unknownType;
+                    }
+                }
+            }
+            // In strict null checking mode, if a default value of a non-undefined type is specified, remove
+            // undefined from the final type.
+            if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkExpressionCached(declaration.initializer)) & 2048 /* Undefined */)) {
+                type = getTypeWithFacts(type, 131072 /* NEUndefined */);
+            }
+            return declaration.initializer ?
+                getUnionType([type, checkExpressionCached(declaration.initializer)], /*subtypeReduction*/ true) :
+                type;
+        }
+        function getTypeForDeclarationFromJSDocComment(declaration) {
+            var jsdocType = ts.getJSDocType(declaration);
+            if (jsdocType) {
+                return getTypeFromTypeNode(jsdocType);
+            }
+            return undefined;
+        }
+        function isNullOrUndefined(node) {
+            var expr = ts.skipParentheses(node);
+            return expr.kind === 95 /* NullKeyword */ || expr.kind === 71 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol;
+        }
+        function isEmptyArrayLiteral(node) {
+            var expr = ts.skipParentheses(node);
+            return expr.kind === 177 /* ArrayLiteralExpression */ && expr.elements.length === 0;
+        }
+        function addOptionality(type, optional) {
+            return strictNullChecks && optional ? getNullableType(type, 2048 /* Undefined */) : type;
+        }
+        // Return the inferred type for a variable, parameter, or property declaration
+        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
+            // A variable declared in a for..in statement is of type string, or of type keyof T when the
+            // right hand expression is of a type parameter type.
+            if (declaration.parent.parent.kind === 215 /* ForInStatement */) {
+                var indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression));
+                return indexType.flags & (16384 /* TypeParameter */ | 262144 /* Index */) ? indexType : stringType;
+            }
+            if (declaration.parent.parent.kind === 216 /* ForOfStatement */) {
+                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
+                // missing properties/signatures required to get its iteratedType (like
+                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
+                // or it may have led to an error inside getElementTypeOfIterable.
+                var forOfStatement = declaration.parent.parent;
+                return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType;
+            }
+            if (ts.isBindingPattern(declaration.parent)) {
+                return getTypeForBindingElement(declaration);
+            }
+            // Use type from type annotation if one is present
+            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
+            if (typeNode) {
+                var declaredType = getTypeFromTypeNode(typeNode);
+                return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
+            }
+            if ((noImplicitAny || ts.isInJavaScriptFile(declaration)) &&
+                declaration.kind === 226 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) &&
+                !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !ts.isInAmbientContext(declaration)) {
+                // If --noImplicitAny is on or the declaration is in a Javascript file,
+                // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
+                // initializer or a 'null' or 'undefined' initializer.
+                if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
+                    return autoType;
+                }
+                // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
+                // literal initializer.
+                if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
+                    return autoArrayType;
+                }
+            }
+            if (declaration.kind === 146 /* Parameter */) {
+                var func = declaration.parent;
+                // For a parameter of a set accessor, use the type of the get accessor if one is present
+                if (func.kind === 154 /* SetAccessor */ && !ts.hasDynamicName(func)) {
+                    var getter = ts.getDeclarationOfKind(declaration.parent.symbol, 153 /* GetAccessor */);
+                    if (getter) {
+                        var getterSignature = getSignatureFromDeclaration(getter);
+                        var thisParameter = getAccessorThisParameter(func);
+                        if (thisParameter && declaration === thisParameter) {
+                            // Use the type from the *getter*
+                            ts.Debug.assert(!thisParameter.type);
+                            return getTypeOfSymbol(getterSignature.thisParameter);
+                        }
+                        return getReturnTypeOfSignature(getterSignature);
+                    }
+                }
+                // Use contextual parameter type if one is available
+                var type = void 0;
+                if (declaration.symbol.escapedName === "this") {
+                    type = getContextualThisParameterType(func);
+                }
+                else {
+                    type = getContextuallyTypedParameterType(declaration);
+                }
+                if (type) {
+                    return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
+                }
+            }
+            // Use the type of the initializer expression if one is present
+            if (declaration.initializer) {
+                var type = checkDeclarationInitializer(declaration);
+                return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
+            }
+            if (ts.isJsxAttribute(declaration)) {
+                // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
+                // I.e <Elem attr /> is sugar for <Elem attr={true} />
+                return trueType;
+            }
+            // If it is a short-hand property assignment, use the type of the identifier
+            if (declaration.kind === 262 /* ShorthandPropertyAssignment */) {
+                return checkIdentifier(declaration.name);
+            }
+            // If the declaration specifies a binding pattern, use the type implied by the binding pattern
+            if (ts.isBindingPattern(declaration.name)) {
+                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
+            }
+            // No type specified and nothing can be inferred
+            return undefined;
+        }
+        function getWidenedTypeFromJSSpecialPropertyDeclarations(symbol) {
+            var types = [];
+            var definedInConstructor = false;
+            var definedInMethod = false;
+            var jsDocType;
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var declaration = _a[_i];
+                var expression = declaration.kind === 194 /* BinaryExpression */ ? declaration :
+                    declaration.kind === 179 /* PropertyAccessExpression */ ? ts.getAncestor(declaration, 194 /* BinaryExpression */) :
+                        undefined;
+                if (!expression) {
+                    return unknownType;
+                }
+                if (ts.isPropertyAccessExpression(expression.left) && expression.left.expression.kind === 99 /* ThisKeyword */) {
+                    if (ts.getThisContainer(expression, /*includeArrowFunctions*/ false).kind === 152 /* Constructor */) {
+                        definedInConstructor = true;
+                    }
+                    else {
+                        definedInMethod = true;
+                    }
+                }
+                // If there is a JSDoc type, use it
+                var type_1 = getTypeForDeclarationFromJSDocComment(expression.parent);
+                if (type_1) {
+                    var declarationType = getWidenedType(type_1);
+                    if (!jsDocType) {
+                        jsDocType = declarationType;
+                    }
+                    else if (jsDocType !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(jsDocType, declarationType)) {
+                        var name = ts.getNameOfDeclaration(declaration);
+                        error(name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(name), typeToString(jsDocType), typeToString(declarationType));
+                    }
+                }
+                else if (!jsDocType) {
+                    // If we don't have an explicit JSDoc type, get the type from the expression.
+                    types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
+                }
+            }
+            var type = jsDocType || getUnionType(types, /*subtypeReduction*/ true);
+            return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
+        }
+        // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
+        // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
+        // pattern. Otherwise, it is the type any.
+        function getTypeFromBindingElement(element, includePatternInType, reportErrors) {
+            if (element.initializer) {
+                return checkDeclarationInitializer(element);
+            }
+            if (ts.isBindingPattern(element.name)) {
+                return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors);
+            }
+            if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
+                reportImplicitAnyError(element, anyType);
+            }
+            return anyType;
+        }
+        // Return the type implied by an object binding pattern
+        function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) {
+            var members = ts.createSymbolTable();
+            var stringIndexInfo;
+            var hasComputedProperties = false;
+            ts.forEach(pattern.elements, function (e) {
+                var name = e.propertyName || e.name;
+                if (isComputedNonLiteralName(name)) {
+                    // do not include computed properties in the implied type
+                    hasComputedProperties = true;
+                    return;
+                }
+                if (e.dotDotDotToken) {
+                    stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
+                    return;
+                }
+                var text = ts.getTextOfPropertyName(name);
+                var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0);
+                var symbol = createSymbol(flags, text);
+                symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
+                symbol.bindingElement = e;
+                members.set(symbol.escapedName, symbol);
+            });
+            var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
+            if (includePatternInType) {
+                result.pattern = pattern;
+            }
+            if (hasComputedProperties) {
+                result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
+            }
+            return result;
+        }
+        // Return the type implied by an array binding pattern
+        function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) {
+            var elements = pattern.elements;
+            var lastElement = ts.lastOrUndefined(elements);
+            if (elements.length === 0 || (!ts.isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) {
+                return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType;
+            }
+            // If the pattern has at least one element, and no rest element, then it should imply a tuple type.
+            var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); });
+            var result = createTupleType(elementTypes);
+            if (includePatternInType) {
+                result = cloneTypeReference(result);
+                result.pattern = pattern;
+            }
+            return result;
+        }
+        // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
+        // and without regard to its context (i.e. without regard any type annotation or initializer associated with the
+        // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any]
+        // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is
+        // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
+        // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
+        // the parameter.
+        function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) {
+            return pattern.kind === 174 /* ObjectBindingPattern */
+                ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
+                : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
+        }
+        // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
+        // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it
+        // is a bit more involved. For example:
+        //
+        //   var [x, s = ""] = [1, "one"];
+        //
+        // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the
+        // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the
+        // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string.
+        function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) {
+            var type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
+            if (type) {
+                if (reportErrors) {
+                    reportErrorsFromWidening(declaration, type);
+                }
+                // During a normal type check we'll never get to here with a property assignment (the check of the containing
+                // object literal uses a different path). We exclude widening only so that language services and type verification
+                // tools see the actual type.
+                if (declaration.kind === 261 /* PropertyAssignment */) {
+                    return type;
+                }
+                return getWidenedType(type);
+            }
+            // Rest parameters default to type any[], other parameters default to type any
+            type = declaration.dotDotDotToken ? anyArrayType : anyType;
+            // Report implicit any errors unless this is a private property within an ambient declaration
+            if (reportErrors && noImplicitAny) {
+                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
+                    reportImplicitAnyError(declaration, type);
+                }
+            }
+            return type;
+        }
+        function declarationBelongsToPrivateAmbientMember(declaration) {
+            var root = ts.getRootDeclaration(declaration);
+            var memberDeclaration = root.kind === 146 /* Parameter */ ? root.parent : root;
+            return isPrivateWithinAmbient(memberDeclaration);
+        }
+        function getTypeOfVariableOrParameterOrProperty(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                // Handle prototype property
+                if (symbol.flags & 4194304 /* Prototype */) {
+                    return links.type = getTypeOfPrototypeProperty(symbol);
+                }
+                // Handle catch clause variables
+                var declaration = symbol.valueDeclaration;
+                if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
+                    return links.type = anyType;
+                }
+                // Handle export default expressions
+                if (declaration.kind === 243 /* ExportAssignment */) {
+                    return links.type = checkExpression(declaration.expression);
+                }
+                if (ts.isInJavaScriptFile(declaration) && ts.isJSDocPropertyLikeTag(declaration) && declaration.typeExpression) {
+                    return links.type = getTypeFromTypeNode(declaration.typeExpression.type);
+                }
+                // Handle variable, parameter or property
+                if (!pushTypeResolution(symbol, 0 /* Type */)) {
+                    return unknownType;
+                }
+                var type = void 0;
+                // Handle certain special assignment kinds, which happen to union across multiple declarations:
+                // * module.exports = expr
+                // * exports.p = expr
+                // * this.p = expr
+                // * className.prototype.method = expr
+                if (declaration.kind === 194 /* BinaryExpression */ ||
+                    declaration.kind === 179 /* PropertyAccessExpression */ && declaration.parent.kind === 194 /* BinaryExpression */) {
+                    type = getWidenedTypeFromJSSpecialPropertyDeclarations(symbol);
+                }
+                else {
+                    type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true);
+                }
+                if (!popTypeResolution()) {
+                    type = reportCircularityError(symbol);
+                }
+                links.type = type;
+            }
+            return links.type;
+        }
+        function getAnnotatedAccessorType(accessor) {
+            if (accessor) {
+                if (accessor.kind === 153 /* GetAccessor */) {
+                    var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor);
+                    return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation);
+                }
+                else {
+                    var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor);
+                    return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
+                }
+            }
+            return undefined;
+        }
+        function getAnnotatedAccessorThisParameter(accessor) {
+            var parameter = getAccessorThisParameter(accessor);
+            return parameter && parameter.symbol;
+        }
+        function getThisTypeOfDeclaration(declaration) {
+            return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
+        }
+        function getTypeOfAccessors(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                var getter = ts.getDeclarationOfKind(symbol, 153 /* GetAccessor */);
+                var setter = ts.getDeclarationOfKind(symbol, 154 /* SetAccessor */);
+                if (getter && ts.isInJavaScriptFile(getter)) {
+                    var jsDocType = getTypeForDeclarationFromJSDocComment(getter);
+                    if (jsDocType) {
+                        return links.type = jsDocType;
+                    }
+                }
+                if (!pushTypeResolution(symbol, 0 /* Type */)) {
+                    return unknownType;
+                }
+                var type = void 0;
+                // First try to see if the user specified a return type on the get-accessor.
+                var getterReturnType = getAnnotatedAccessorType(getter);
+                if (getterReturnType) {
+                    type = getterReturnType;
+                }
+                else {
+                    // If the user didn't specify a return type, try to use the set-accessor's parameter type.
+                    var setterParameterType = getAnnotatedAccessorType(setter);
+                    if (setterParameterType) {
+                        type = setterParameterType;
+                    }
+                    else {
+                        // If there are no specified types, try to infer it from the body of the get accessor if it exists.
+                        if (getter && getter.body) {
+                            type = getReturnTypeFromBody(getter);
+                        }
+                        else {
+                            if (noImplicitAny) {
+                                if (setter) {
+                                    error(setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
+                                }
+                                else {
+                                    ts.Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
+                                    error(getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
+                                }
+                            }
+                            type = anyType;
+                        }
+                    }
+                }
+                if (!popTypeResolution()) {
+                    type = anyType;
+                    if (noImplicitAny) {
+                        var getter_1 = ts.getDeclarationOfKind(symbol, 153 /* GetAccessor */);
+                        error(getter_1, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
+                    }
+                }
+                links.type = type;
+            }
+            return links.type;
+        }
+        function getBaseTypeVariableOfClass(symbol) {
+            var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
+            return baseConstructorType.flags & 540672 /* TypeVariable */ ? baseConstructorType : undefined;
+        }
+        function getTypeOfFuncClassEnumModule(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) {
+                    links.type = anyType;
+                }
+                else {
+                    var type = createObjectType(16 /* Anonymous */, symbol);
+                    if (symbol.flags & 32 /* Class */) {
+                        var baseTypeVariable = getBaseTypeVariableOfClass(symbol);
+                        links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
+                    }
+                    else {
+                        links.type = strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getNullableType(type, 2048 /* Undefined */) : type;
+                    }
+                }
+            }
+            return links.type;
+        }
+        function getTypeOfEnumMember(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                links.type = getDeclaredTypeOfEnumMember(symbol);
+            }
+            return links.type;
+        }
+        function getTypeOfAlias(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                var targetSymbol = resolveAlias(symbol);
+                // It only makes sense to get the type of a value symbol. If the result of resolving
+                // the alias is not a value, then it has no type. To get the type associated with a
+                // type symbol, call getDeclaredTypeOfSymbol.
+                // This check is important because without it, a call to getTypeOfSymbol could end
+                // up recursively calling getTypeOfAlias, causing a stack overflow.
+                links.type = targetSymbol.flags & 107455 /* Value */
+                    ? getTypeOfSymbol(targetSymbol)
+                    : unknownType;
+            }
+            return links.type;
+        }
+        function getTypeOfInstantiatedSymbol(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.type) {
+                if (symbolInstantiationDepth === 100) {
+                    error(symbol.valueDeclaration, ts.Diagnostics.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite);
+                    links.type = unknownType;
+                }
+                else {
+                    if (!pushTypeResolution(symbol, 0 /* Type */)) {
+                        return unknownType;
+                    }
+                    symbolInstantiationDepth++;
+                    var type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
+                    symbolInstantiationDepth--;
+                    if (!popTypeResolution()) {
+                        type = reportCircularityError(symbol);
+                    }
+                    links.type = type;
+                }
+            }
+            return links.type;
+        }
+        function reportCircularityError(symbol) {
+            // Check if variable has type annotation that circularly references the variable itself
+            if (ts.getEffectiveTypeAnnotationNode(symbol.valueDeclaration)) {
+                error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
+                return unknownType;
+            }
+            // Otherwise variable has initializer that circularly references the variable itself
+            if (noImplicitAny) {
+                error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
+            }
+            return anyType;
+        }
+        function getTypeOfSymbol(symbol) {
+            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
+                return getTypeOfInstantiatedSymbol(symbol);
+            }
+            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
+                return getTypeOfVariableOrParameterOrProperty(symbol);
+            }
+            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
+                return getTypeOfFuncClassEnumModule(symbol);
+            }
+            if (symbol.flags & 8 /* EnumMember */) {
+                return getTypeOfEnumMember(symbol);
+            }
+            if (symbol.flags & 98304 /* Accessor */) {
+                return getTypeOfAccessors(symbol);
+            }
+            if (symbol.flags & 2097152 /* Alias */) {
+                return getTypeOfAlias(symbol);
+            }
+            return unknownType;
+        }
+        function isReferenceToType(type, target) {
+            return type !== undefined
+                && target !== undefined
+                && (getObjectFlags(type) & 4 /* Reference */) !== 0
+                && type.target === target;
+        }
+        function getTargetType(type) {
+            return getObjectFlags(type) & 4 /* Reference */ ? type.target : type;
+        }
+        function hasBaseType(type, checkBase) {
+            return check(type);
+            function check(type) {
+                if (getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) {
+                    var target = getTargetType(type);
+                    return target === checkBase || ts.forEach(getBaseTypes(target), check);
+                }
+                else if (type.flags & 131072 /* Intersection */) {
+                    return ts.forEach(type.types, check);
+                }
+            }
+        }
+        // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
+        // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
+        // in-place and returns the same array.
+        function appendTypeParameters(typeParameters, declarations) {
+            for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
+                var declaration = declarations_2[_i];
+                var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
+                typeParameters = ts.appendIfUnique(typeParameters, tp);
+            }
+            return typeParameters;
+        }
+        // Return the outer type parameters of a node or undefined if the node has no outer type parameters.
+        function getOuterTypeParameters(node, includeThisTypes) {
+            while (true) {
+                node = node.parent;
+                if (!node) {
+                    return undefined;
+                }
+                switch (node.kind) {
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 155 /* CallSignature */:
+                    case 156 /* ConstructSignature */:
+                    case 150 /* MethodSignature */:
+                    case 160 /* FunctionType */:
+                    case 161 /* ConstructorType */:
+                    case 273 /* JSDocFunctionType */:
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 282 /* JSDocTemplateTag */:
+                    case 172 /* MappedType */:
+                        var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
+                        if (node.kind === 172 /* MappedType */) {
+                            return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)));
+                        }
+                        var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray);
+                        var thisType = includeThisTypes &&
+                            (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || node.kind === 230 /* InterfaceDeclaration */) &&
+                            getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
+                        return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
+                }
+            }
+        }
+        // The outer type parameters are those defined by enclosing generic classes, methods, or functions.
+        function getOuterTypeParametersOfClassOrInterface(symbol) {
+            var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */);
+            return getOuterTypeParameters(declaration);
+        }
+        // The local type parameters are the combined set of type parameters from all declarations of the class,
+        // interface, or type alias.
+        function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
+            var result;
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var node = _a[_i];
+                if (node.kind === 230 /* InterfaceDeclaration */ || node.kind === 229 /* ClassDeclaration */ ||
+                    node.kind === 199 /* ClassExpression */ || node.kind === 231 /* TypeAliasDeclaration */) {
+                    var declaration = node;
+                    if (declaration.typeParameters) {
+                        result = appendTypeParameters(result, declaration.typeParameters);
+                    }
+                }
+            }
+            return result;
+        }
+        // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
+        // its locally declared type parameters.
+        function getTypeParametersOfClassOrInterface(symbol) {
+            return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
+        }
+        // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
+        // rest parameter of type any[].
+        function isMixinConstructorType(type) {
+            var signatures = getSignaturesOfType(type, 1 /* Construct */);
+            if (signatures.length === 1) {
+                var s = signatures[0];
+                return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType;
+            }
+            return false;
+        }
+        function isConstructorType(type) {
+            if (isValidBaseType(type) && getSignaturesOfType(type, 1 /* Construct */).length > 0) {
+                return true;
+            }
+            if (type.flags & 540672 /* TypeVariable */) {
+                var constraint = getBaseConstraintOfType(type);
+                return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
+            }
+            return false;
+        }
+        function getBaseTypeNodeOfClass(type) {
+            var decl = type.symbol.valueDeclaration;
+            if (ts.isInJavaScriptFile(decl)) {
+                // Prefer an @augments tag because it may have type parameters.
+                var tag = ts.getJSDocAugmentsTag(decl);
+                if (tag) {
+                    return tag.class;
+                }
+            }
+            return ts.getClassExtendsHeritageClauseElement(decl);
+        }
+        function getConstructorsForTypeArguments(type, typeArgumentNodes, location) {
+            var typeArgCount = ts.length(typeArgumentNodes);
+            var isJavaScript = ts.isInJavaScriptFile(location);
+            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); });
+        }
+        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) {
+            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
+            var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode);
+            return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJavaScriptFile(location)) : sig; });
+        }
+        /**
+         * The base constructor of a class can resolve to
+         * * undefinedType if the class has no extends clause,
+         * * unknownType if an error occurred during resolution of the extends expression,
+         * * nullType if the extends expression is the null value,
+         * * anyType if the extends expression has type any, or
+         * * an object type with at least one construct signature.
+         */
+        function getBaseConstructorTypeOfClass(type) {
+            if (!type.resolvedBaseConstructorType) {
+                var decl = type.symbol.valueDeclaration;
+                var extended = ts.getClassExtendsHeritageClauseElement(decl);
+                var baseTypeNode = getBaseTypeNodeOfClass(type);
+                if (!baseTypeNode) {
+                    return type.resolvedBaseConstructorType = undefinedType;
+                }
+                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
+                    return unknownType;
+                }
+                var baseConstructorType = checkExpression(baseTypeNode.expression);
+                if (extended && baseTypeNode !== extended) {
+                    ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
+                    checkExpression(extended.expression);
+                }
+                if (baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */)) {
+                    // Resolving the members of a class requires us to resolve the base class of that class.
+                    // We force resolution here such that we catch circularities now.
+                    resolveStructuredTypeMembers(baseConstructorType);
+                }
+                if (!popTypeResolution()) {
+                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
+                    return type.resolvedBaseConstructorType = unknownType;
+                }
+                if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
+                    error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
+                    return type.resolvedBaseConstructorType = unknownType;
+                }
+                type.resolvedBaseConstructorType = baseConstructorType;
+            }
+            return type.resolvedBaseConstructorType;
+        }
+        function getBaseTypes(type) {
+            if (!type.resolvedBaseTypes) {
+                if (type.objectFlags & 8 /* Tuple */) {
+                    type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))];
+                }
+                else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
+                    if (type.symbol.flags & 32 /* Class */) {
+                        resolveBaseTypesOfClass(type);
+                    }
+                    if (type.symbol.flags & 64 /* Interface */) {
+                        resolveBaseTypesOfInterface(type);
+                    }
+                }
+                else {
+                    ts.Debug.fail("type must be class or interface");
+                }
+            }
+            return type.resolvedBaseTypes;
+        }
+        function resolveBaseTypesOfClass(type) {
+            type.resolvedBaseTypes = ts.emptyArray;
+            var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
+            if (!(baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */ | 1 /* Any */))) {
+                return;
+            }
+            var baseTypeNode = getBaseTypeNodeOfClass(type);
+            var typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
+            var baseType;
+            var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+            if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
+                areAllOuterTypeParametersApplied(originalBaseType)) {
+                // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
+                // class and all return the instance type of the class. There is no need for further checks and we can apply the
+                // type arguments in the same manner as a type reference to get the same error reporting experience.
+                baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs);
+            }
+            else if (baseConstructorType.flags & 1 /* Any */) {
+                baseType = baseConstructorType;
+            }
+            else {
+                // The class derives from a "class-like" constructor function, check that we have at least one construct signature
+                // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
+                // we check that all instantiated signatures return the same type.
+                var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
+                if (!constructors.length) {
+                    error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
+                    return;
+                }
+                baseType = getReturnTypeOfSignature(constructors[0]);
+            }
+            if (baseType === unknownType) {
+                return;
+            }
+            if (!isValidBaseType(baseType)) {
+                error(baseTypeNode.expression, ts.Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
+                return;
+            }
+            if (type === baseType || hasBaseType(baseType, type)) {
+                error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */));
+                return;
+            }
+            type.resolvedBaseTypes = [baseType];
+        }
+        function areAllOuterTypeParametersApplied(type) {
+            // An unapplied type parameter has its symbol still the same as the matching argument symbol.
+            // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
+            var outerTypeParameters = type.outerTypeParameters;
+            if (outerTypeParameters) {
+                var last_1 = outerTypeParameters.length - 1;
+                var typeArguments = type.typeArguments;
+                return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol;
+            }
+            return true;
+        }
+        // A valid base type is `any`, any non-generic object type or intersection of non-generic
+        // object types.
+        function isValidBaseType(type) {
+            return type.flags & (32768 /* Object */ | 16777216 /* NonPrimitive */ | 1 /* Any */) && !isGenericMappedType(type) ||
+                type.flags & 131072 /* Intersection */ && !ts.forEach(type.types, function (t) { return !isValidBaseType(t); });
+        }
+        function resolveBaseTypesOfInterface(type) {
+            type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray;
+            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
+                var declaration = _a[_i];
+                if (declaration.kind === 230 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) {
+                    for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) {
+                        var node = _c[_b];
+                        var baseType = getTypeFromTypeNode(node);
+                        if (baseType !== unknownType) {
+                            if (isValidBaseType(baseType)) {
+                                if (type !== baseType && !hasBaseType(baseType, type)) {
+                                    if (type.resolvedBaseTypes === ts.emptyArray) {
+                                        type.resolvedBaseTypes = [baseType];
+                                    }
+                                    else {
+                                        type.resolvedBaseTypes.push(baseType);
+                                    }
+                                }
+                                else {
+                                    error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */));
+                                }
+                            }
+                            else {
+                                error(node, ts.Diagnostics.An_interface_may_only_extend_a_class_or_another_interface);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        // Returns true if the interface given by the symbol is free of "this" references. Specifically, the result is
+        // true if the interface itself contains no references to "this" in its body, if all base types are interfaces,
+        // and if none of the base interfaces have a "this" type.
+        function isIndependentInterface(symbol) {
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var declaration = _a[_i];
+                if (declaration.kind === 230 /* InterfaceDeclaration */) {
+                    if (declaration.flags & 64 /* ContainsThis */) {
+                        return false;
+                    }
+                    var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration);
+                    if (baseTypeNodes) {
+                        for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) {
+                            var node = baseTypeNodes_1[_b];
+                            if (ts.isEntityNameExpression(node.expression)) {
+                                var baseSymbol = resolveEntityName(node.expression, 793064 /* Type */, /*ignoreErrors*/ true);
+                                if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return true;
+        }
+        function getDeclaredTypeOfClassOrInterface(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.declaredType) {
+                var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */;
+                var type = links.declaredType = createObjectType(kind, symbol);
+                var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
+                var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
+                // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type
+                // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular,
+                // property types inferred from initializers and method return types inferred from return statements are very hard
+                // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of
+                // "this" references.
+                if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isIndependentInterface(symbol)) {
+                    type.objectFlags |= 4 /* Reference */;
+                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
+                    type.outerTypeParameters = outerTypeParameters;
+                    type.localTypeParameters = localTypeParameters;
+                    type.instantiations = ts.createMap();
+                    type.instantiations.set(getTypeListId(type.typeParameters), type);
+                    type.target = type;
+                    type.typeArguments = type.typeParameters;
+                    type.thisType = createType(16384 /* TypeParameter */);
+                    type.thisType.isThisType = true;
+                    type.thisType.symbol = symbol;
+                    type.thisType.constraint = type;
+                }
+            }
+            return links.declaredType;
+        }
+        function getDeclaredTypeOfTypeAlias(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.declaredType) {
+                // Note that we use the links object as the target here because the symbol object is used as the unique
+                // identity for resolution of the 'type' property in SymbolLinks.
+                if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) {
+                    return unknownType;
+                }
+                var declaration = ts.find(symbol.declarations, function (d) {
+                    return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */;
+                });
+                var typeNode = declaration.kind === 283 /* JSDocTypedefTag */ ? declaration.typeExpression : declaration.type;
+                // If typeNode is missing, we will error in checkJSDocTypedefTag.
+                var type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType;
+                if (popTypeResolution()) {
+                    var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
+                    if (typeParameters) {
+                        // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
+                        // an instantiation of the type alias with the type parameters supplied as type arguments.
+                        links.typeParameters = typeParameters;
+                        links.instantiations = ts.createMap();
+                        links.instantiations.set(getTypeListId(typeParameters), type);
+                    }
+                }
+                else {
+                    type = unknownType;
+                    error(declaration.name, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
+                }
+                links.declaredType = type;
+            }
+            return links.declaredType;
+        }
+        function isLiteralEnumMember(member) {
+            var expr = member.initializer;
+            if (!expr) {
+                return !ts.isInAmbientContext(member);
+            }
+            switch (expr.kind) {
+                case 9 /* StringLiteral */:
+                case 8 /* NumericLiteral */:
+                    return true;
+                case 192 /* PrefixUnaryExpression */:
+                    return expr.operator === 38 /* MinusToken */ &&
+                        expr.operand.kind === 8 /* NumericLiteral */;
+                case 71 /* Identifier */:
+                    return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText);
+                default:
+                    return false;
+            }
+        }
+        function getEnumKind(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (links.enumKind !== undefined) {
+                return links.enumKind;
+            }
+            var hasNonLiteralMember = false;
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var declaration = _a[_i];
+                if (declaration.kind === 232 /* EnumDeclaration */) {
+                    for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
+                        var member = _c[_b];
+                        if (member.initializer && member.initializer.kind === 9 /* StringLiteral */) {
+                            return links.enumKind = 1 /* Literal */;
+                        }
+                        if (!isLiteralEnumMember(member)) {
+                            hasNonLiteralMember = true;
+                        }
+                    }
+                }
+            }
+            return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */;
+        }
+        function getBaseTypeOfEnumLiteralType(type) {
+            return type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
+        }
+        function getDeclaredTypeOfEnum(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (links.declaredType) {
+                return links.declaredType;
+            }
+            if (getEnumKind(symbol) === 1 /* Literal */) {
+                enumCount++;
+                var memberTypeList = [];
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var declaration = _a[_i];
+                    if (declaration.kind === 232 /* EnumDeclaration */) {
+                        for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
+                            var member = _c[_b];
+                            var memberType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member));
+                            getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
+                            memberTypeList.push(memberType);
+                        }
+                    }
+                }
+                if (memberTypeList.length) {
+                    var enumType_1 = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined);
+                    if (enumType_1.flags & 65536 /* Union */) {
+                        enumType_1.flags |= 256 /* EnumLiteral */;
+                        enumType_1.symbol = symbol;
+                    }
+                    return links.declaredType = enumType_1;
+                }
+            }
+            var enumType = createType(16 /* Enum */);
+            enumType.symbol = symbol;
+            return links.declaredType = enumType;
+        }
+        function getDeclaredTypeOfEnumMember(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.declaredType) {
+                var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
+                if (!links.declaredType) {
+                    links.declaredType = enumType;
+                }
+            }
+            return links.declaredType;
+        }
+        function getDeclaredTypeOfTypeParameter(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.declaredType) {
+                var type = createType(16384 /* TypeParameter */);
+                type.symbol = symbol;
+                links.declaredType = type;
+            }
+            return links.declaredType;
+        }
+        function getDeclaredTypeOfAlias(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.declaredType) {
+                links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol));
+            }
+            return links.declaredType;
+        }
+        function getDeclaredTypeOfSymbol(symbol) {
+            return tryGetDeclaredTypeOfSymbol(symbol) || unknownType;
+        }
+        function tryGetDeclaredTypeOfSymbol(symbol) {
+            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
+                return getDeclaredTypeOfClassOrInterface(symbol);
+            }
+            if (symbol.flags & 524288 /* TypeAlias */) {
+                return getDeclaredTypeOfTypeAlias(symbol);
+            }
+            if (symbol.flags & 262144 /* TypeParameter */) {
+                return getDeclaredTypeOfTypeParameter(symbol);
+            }
+            if (symbol.flags & 384 /* Enum */) {
+                return getDeclaredTypeOfEnum(symbol);
+            }
+            if (symbol.flags & 8 /* EnumMember */) {
+                return getDeclaredTypeOfEnumMember(symbol);
+            }
+            if (symbol.flags & 2097152 /* Alias */) {
+                return getDeclaredTypeOfAlias(symbol);
+            }
+            return undefined;
+        }
+        // A type reference is considered independent if each type argument is considered independent.
+        function isIndependentTypeReference(node) {
+            if (node.typeArguments) {
+                for (var _i = 0, _a = node.typeArguments; _i < _a.length; _i++) {
+                    var typeNode = _a[_i];
+                    if (!isIndependentType(typeNode)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        // A type is considered independent if it the any, string, number, boolean, symbol, or void keyword, a string
+        // literal type, an array with an element type that is considered independent, or a type reference that is
+        // considered independent.
+        function isIndependentType(node) {
+            switch (node.kind) {
+                case 119 /* AnyKeyword */:
+                case 136 /* StringKeyword */:
+                case 133 /* NumberKeyword */:
+                case 122 /* BooleanKeyword */:
+                case 137 /* SymbolKeyword */:
+                case 134 /* ObjectKeyword */:
+                case 105 /* VoidKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 95 /* NullKeyword */:
+                case 130 /* NeverKeyword */:
+                case 173 /* LiteralType */:
+                    return true;
+                case 164 /* ArrayType */:
+                    return isIndependentType(node.elementType);
+                case 159 /* TypeReference */:
+                    return isIndependentTypeReference(node);
+            }
+            return false;
+        }
+        // A variable-like declaration is considered independent (free of this references) if it has a type annotation
+        // that specifies an independent type, or if it has no type annotation and no initializer (and thus of type any).
+        function isIndependentVariableLikeDeclaration(node) {
+            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
+            return typeNode ? isIndependentType(typeNode) : !node.initializer;
+        }
+        // A function-like declaration is considered independent (free of this references) if it has a return type
+        // annotation that is considered independent and if each parameter is considered independent.
+        function isIndependentFunctionLikeDeclaration(node) {
+            if (node.kind !== 152 /* Constructor */) {
+                var typeNode = ts.getEffectiveReturnTypeNode(node);
+                if (!typeNode || !isIndependentType(typeNode)) {
+                    return false;
+                }
+            }
+            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
+                var parameter = _a[_i];
+                if (!isIndependentVariableLikeDeclaration(parameter)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        // Returns true if the class or interface member given by the symbol is free of "this" references. The
+        // function may return false for symbols that are actually free of "this" references because it is not
+        // feasible to perform a complete analysis in all cases. In particular, property members with types
+        // inferred from their initializers and function members with inferred return types are conservatively
+        // assumed not to be free of "this" references.
+        function isIndependentMember(symbol) {
+            if (symbol.declarations && symbol.declarations.length === 1) {
+                var declaration = symbol.declarations[0];
+                if (declaration) {
+                    switch (declaration.kind) {
+                        case 149 /* PropertyDeclaration */:
+                        case 148 /* PropertySignature */:
+                            return isIndependentVariableLikeDeclaration(declaration);
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 152 /* Constructor */:
+                            return isIndependentFunctionLikeDeclaration(declaration);
+                    }
+                }
+            }
+            return false;
+        }
+        // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
+        // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
+        function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
+            var result = ts.createSymbolTable();
+            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
+                var symbol = symbols_2[_i];
+                result.set(symbol.escapedName, mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper));
+            }
+            return result;
+        }
+        function addInheritedMembers(symbols, baseSymbols) {
+            for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) {
+                var s = baseSymbols_1[_i];
+                if (!symbols.has(s.escapedName)) {
+                    symbols.set(s.escapedName, s);
+                }
+            }
+        }
+        function resolveDeclaredMembers(type) {
+            if (!type.declaredProperties) {
+                var symbol = type.symbol;
+                type.declaredProperties = getNamedMembers(symbol.members);
+                type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members.get("__call" /* Call */));
+                type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members.get("__new" /* New */));
+                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
+                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
+            }
+            return type;
+        }
+        function getTypeWithThisArgument(type, thisArgument) {
+            if (getObjectFlags(type) & 4 /* Reference */) {
+                var target = type.target;
+                var typeArguments = type.typeArguments;
+                if (ts.length(target.typeParameters) === ts.length(typeArguments)) {
+                    return createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType]));
+                }
+            }
+            else if (type.flags & 131072 /* Intersection */) {
+                return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument); }));
+            }
+            return type;
+        }
+        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
+            var mapper;
+            var members;
+            var callSignatures;
+            var constructSignatures;
+            var stringIndexInfo;
+            var numberIndexInfo;
+            if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
+                mapper = identityMapper;
+                members = source.symbol ? source.symbol.members : ts.createSymbolTable(source.declaredProperties);
+                callSignatures = source.declaredCallSignatures;
+                constructSignatures = source.declaredConstructSignatures;
+                stringIndexInfo = source.declaredStringIndexInfo;
+                numberIndexInfo = source.declaredNumberIndexInfo;
+            }
+            else {
+                mapper = createTypeMapper(typeParameters, typeArguments);
+                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
+                callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
+                constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
+                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
+                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
+            }
+            var baseTypes = getBaseTypes(source);
+            if (baseTypes.length) {
+                if (source.symbol && members === source.symbol.members) {
+                    members = ts.createSymbolTable(source.declaredProperties);
+                }
+                var thisArgument = ts.lastOrUndefined(typeArguments);
+                for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) {
+                    var baseType = baseTypes_1[_i];
+                    var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
+                    addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType));
+                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
+                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
+                    if (!stringIndexInfo) {
+                        stringIndexInfo = instantiatedBaseType === anyType ?
+                            createIndexInfo(anyType, /*isReadonly*/ false) :
+                            getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
+                    }
+                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
+                }
+            }
+            setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+        }
+        function resolveClassOrInterfaceMembers(type) {
+            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray);
+        }
+        function resolveTypeReferenceMembers(type) {
+            var source = resolveDeclaredMembers(type.target);
+            var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]);
+            var typeArguments = type.typeArguments && type.typeArguments.length === typeParameters.length ?
+                type.typeArguments : ts.concatenate(type.typeArguments, [type]);
+            resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
+        }
+        function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, typePredicate, minArgumentCount, hasRestParameter, hasLiteralTypes) {
+            var sig = new Signature(checker);
+            sig.declaration = declaration;
+            sig.typeParameters = typeParameters;
+            sig.parameters = parameters;
+            sig.thisParameter = thisParameter;
+            sig.resolvedReturnType = resolvedReturnType;
+            sig.typePredicate = typePredicate;
+            sig.minArgumentCount = minArgumentCount;
+            sig.hasRestParameter = hasRestParameter;
+            sig.hasLiteralTypes = hasLiteralTypes;
+            return sig;
+        }
+        function cloneSignature(sig) {
+            return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
+        }
+        function getDefaultConstructSignatures(classType) {
+            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
+            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
+            if (baseSignatures.length === 0) {
+                return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
+            }
+            var baseTypeNode = getBaseTypeNodeOfClass(classType);
+            var isJavaScript = ts.isInJavaScriptFile(baseTypeNode);
+            var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
+            var typeArgCount = ts.length(typeArguments);
+            var result = [];
+            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
+                var baseSig = baseSignatures_1[_i];
+                var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
+                var typeParamCount = ts.length(baseSig.typeParameters);
+                if ((isJavaScript || typeArgCount >= minTypeArgumentCount) && typeArgCount <= typeParamCount) {
+                    var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
+                    sig.typeParameters = classType.localTypeParameters;
+                    sig.resolvedReturnType = classType;
+                    result.push(sig);
+                }
+            }
+            return result;
+        }
+        function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) {
+            for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) {
+                var s = signatureList_1[_i];
+                if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) {
+                    return s;
+                }
+            }
+        }
+        function findMatchingSignatures(signatureLists, signature, listIndex) {
+            if (signature.typeParameters) {
+                // We require an exact match for generic signatures, so we only return signatures from the first
+                // signature list and only if they have exact matches in the other signature lists.
+                if (listIndex > 0) {
+                    return undefined;
+                }
+                for (var i = 1; i < signatureLists.length; i++) {
+                    if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) {
+                        return undefined;
+                    }
+                }
+                return [signature];
+            }
+            var result = undefined;
+            for (var i = 0; i < signatureLists.length; i++) {
+                // Allow matching non-generic signatures to have excess parameters and different return types
+                var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true);
+                if (!match) {
+                    return undefined;
+                }
+                result = ts.appendIfUnique(result, match);
+            }
+            return result;
+        }
+        // The signatures of a union type are those signatures that are present in each of the constituent types.
+        // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional
+        // parameters and may differ in return types. When signatures differ in return types, the resulting return
+        // type is the union of the constituent return types.
+        function getUnionSignatures(types, kind) {
+            var signatureLists = ts.map(types, function (t) { return getSignaturesOfType(t, kind); });
+            var result = undefined;
+            for (var i = 0; i < signatureLists.length; i++) {
+                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
+                    var signature = _a[_i];
+                    // Only process signatures with parameter lists that aren't already in the result list
+                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) {
+                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
+                        if (unionSignatures) {
+                            var s = signature;
+                            // Union the result types when more than one signature matches
+                            if (unionSignatures.length > 1) {
+                                s = cloneSignature(signature);
+                                if (ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; })) {
+                                    var thisType = getUnionType(ts.map(unionSignatures, function (sig) { return getTypeOfSymbol(sig.thisParameter) || anyType; }), /*subtypeReduction*/ true);
+                                    s.thisParameter = createSymbolWithType(signature.thisParameter, thisType);
+                                }
+                                // Clear resolved return type we possibly got from cloneSignature
+                                s.resolvedReturnType = undefined;
+                                s.unionSignatures = unionSignatures;
+                            }
+                            (result || (result = [])).push(s);
+                        }
+                    }
+                }
+            }
+            return result || ts.emptyArray;
+        }
+        function getUnionIndexInfo(types, kind) {
+            var indexTypes = [];
+            var isAnyReadonly = false;
+            for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
+                var type = types_1[_i];
+                var indexInfo = getIndexInfoOfType(type, kind);
+                if (!indexInfo) {
+                    return undefined;
+                }
+                indexTypes.push(indexInfo.type);
+                isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
+            }
+            return createIndexInfo(getUnionType(indexTypes, /*subtypeReduction*/ true), isAnyReadonly);
+        }
+        function resolveUnionTypeMembers(type) {
+            // The members and properties collections are empty for union types. To get all properties of a union
+            // type use getPropertiesOfType (only the language service uses this).
+            var callSignatures = getUnionSignatures(type.types, 0 /* Call */);
+            var constructSignatures = getUnionSignatures(type.types, 1 /* Construct */);
+            var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */);
+            var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */);
+            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+        }
+        function intersectTypes(type1, type2) {
+            return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]);
+        }
+        function intersectIndexInfos(info1, info2) {
+            return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
+        }
+        function unionSpreadIndexInfos(info1, info2) {
+            return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
+        }
+        function includeMixinType(type, types, index) {
+            var mixedTypes = [];
+            for (var i = 0; i < types.length; i++) {
+                if (i === index) {
+                    mixedTypes.push(type);
+                }
+                else if (isMixinConstructorType(types[i])) {
+                    mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0]));
+                }
+            }
+            return getIntersectionType(mixedTypes);
+        }
+        function resolveIntersectionTypeMembers(type) {
+            // The members and properties collections are empty for intersection types. To get all properties of an
+            // intersection type use getPropertiesOfType (only the language service uses this).
+            var callSignatures = ts.emptyArray;
+            var constructSignatures = ts.emptyArray;
+            var stringIndexInfo;
+            var numberIndexInfo;
+            var types = type.types;
+            var mixinCount = ts.countWhere(types, isMixinConstructorType);
+            var _loop_3 = function (i) {
+                var t = type.types[i];
+                // When an intersection type contains mixin constructor types, the construct signatures from
+                // those types are discarded and their return types are mixed into the return types of all
+                // other construct signatures in the intersection type. For example, the intersection type
+                // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
+                // 'new(s: string) => A & B'.
+                if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) {
+                    var signatures = getSignaturesOfType(t, 1 /* Construct */);
+                    if (signatures.length && mixinCount > 0) {
+                        signatures = ts.map(signatures, function (s) {
+                            var clone = cloneSignature(s);
+                            clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i);
+                            return clone;
+                        });
+                    }
+                    constructSignatures = ts.concatenate(constructSignatures, signatures);
+                }
+                callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(t, 0 /* Call */));
+                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
+                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
+            };
+            for (var i = 0; i < types.length; i++) {
+                _loop_3(i);
+            }
+            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+        }
+        /**
+         * Converts an AnonymousType to a ResolvedType.
+         */
+        function resolveAnonymousTypeMembers(type) {
+            var symbol = type.symbol;
+            if (type.target) {
+                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
+                var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper);
+                var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper);
+                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
+                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
+                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+            }
+            else if (symbol.flags & 2048 /* TypeLiteral */) {
+                var members = symbol.members;
+                var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
+                var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
+                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
+                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
+                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+            }
+            else {
+                // Combinations of function, class, enum and module
+                var members = emptySymbols;
+                var stringIndexInfo = undefined;
+                if (symbol.exports) {
+                    members = getExportsOfSymbol(symbol);
+                }
+                if (symbol.flags & 32 /* Class */) {
+                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
+                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
+                    if (baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */ | 540672 /* TypeVariable */)) {
+                        members = ts.createSymbolTable(getNamedMembers(members));
+                        addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
+                    }
+                    else if (baseConstructorType === anyType) {
+                        stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
+                    }
+                }
+                var numberIndexInfo = symbol.flags & 384 /* Enum */ ? enumNumberIndexInfo : undefined;
+                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
+                // We resolve the members before computing the signatures because a signature may use
+                // typeof with a qualified name expression that circularly references the type we are
+                // in the process of resolving (see issue #6072). The temporarily empty signature list
+                // will never be observed because a qualified name can't reference signatures.
+                if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
+                    type.callSignatures = getSignaturesOfSymbol(symbol);
+                }
+                // And likewise for construct signatures for classes
+                if (symbol.flags & 32 /* Class */) {
+                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
+                    var constructSignatures = getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */));
+                    if (!constructSignatures.length) {
+                        constructSignatures = getDefaultConstructSignatures(classType);
+                    }
+                    type.constructSignatures = constructSignatures;
+                }
+            }
+        }
+        /** Resolve the members of a mapped type { [P in K]: T } */
+        function resolveMappedTypeMembers(type) {
+            var members = ts.createSymbolTable();
+            var stringIndexInfo;
+            // Resolve upfront such that recursive references see an empty object type.
+            setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
+            // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
+            // and T as the template type.
+            var typeParameter = getTypeParameterFromMappedType(type);
+            var constraintType = getConstraintTypeFromMappedType(type);
+            var templateType = getTemplateTypeFromMappedType(type);
+            var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
+            var templateReadonly = !!type.declaration.readonlyToken;
+            var templateOptional = !!type.declaration.questionToken;
+            if (type.declaration.typeParameter.constraint.kind === 170 /* TypeOperator */) {
+                // We have a { [P in keyof T]: X }
+                for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) {
+                    var propertySymbol = _a[_i];
+                    addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol);
+                }
+                if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) {
+                    addMemberForKeyType(stringType);
+                }
+            }
+            else {
+                // First, if the constraint type is a type parameter, obtain the base constraint. Then,
+                // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
+                // Finally, iterate over the constituents of the resulting iteration type.
+                var keyType = constraintType.flags & 540672 /* TypeVariable */ ? getApparentType(constraintType) : constraintType;
+                var iterationType = keyType.flags & 262144 /* Index */ ? getIndexType(getApparentType(keyType.type)) : keyType;
+                forEachType(iterationType, addMemberForKeyType);
+            }
+            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
+            function addMemberForKeyType(t, propertySymbolOrIndex) {
+                var propertySymbol;
+                // forEachType delegates to forEach, which calls with a numeric second argument
+                //  the type system currently doesn't catch this incompatibility, so we annotate
+                //  the function ourselves to indicate the runtime behavior and deal with it here
+                if (typeof propertySymbolOrIndex === "object") {
+                    propertySymbol = propertySymbolOrIndex;
+                }
+                // Create a mapper from T to the current iteration type constituent. Then, if the
+                // mapped type is itself an instantiated type, combine the iteration mapper with the
+                // instantiation mapper.
+                var iterationMapper = createTypeMapper([typeParameter], [t]);
+                var templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
+                var propType = instantiateType(templateType, templateMapper);
+                // If the current iteration type constituent is a string literal type, create a property.
+                // Otherwise, for type string create a string index signature.
+                if (t.flags & 32 /* StringLiteral */) {
+                    var propName = ts.escapeLeadingUnderscores(t.value);
+                    var modifiersProp = getPropertyOfType(modifiersType, propName);
+                    var isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & 16777216 /* Optional */);
+                    var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName);
+                    prop.checkFlags = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp) ? 8 /* Readonly */ : 0;
+                    prop.type = propType;
+                    if (propertySymbol) {
+                        prop.syntheticOrigin = propertySymbol;
+                        prop.declarations = propertySymbol.declarations;
+                    }
+                    prop.syntheticLiteralTypeOrigin = t;
+                    members.set(propName, prop);
+                }
+                else if (t.flags & (1 /* Any */ | 2 /* String */)) {
+                    stringIndexInfo = createIndexInfo(propType, templateReadonly);
+                }
+            }
+        }
+        function getTypeParameterFromMappedType(type) {
+            return type.typeParameter ||
+                (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
+        }
+        function getConstraintTypeFromMappedType(type) {
+            return type.constraintType ||
+                (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType);
+        }
+        function getTemplateTypeFromMappedType(type) {
+            return type.templateType ||
+                (type.templateType = type.declaration.type ?
+                    instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) :
+                    unknownType);
+        }
+        function getModifiersTypeFromMappedType(type) {
+            if (!type.modifiersType) {
+                var constraintDeclaration = type.declaration.typeParameter.constraint;
+                if (constraintDeclaration.kind === 170 /* TypeOperator */) {
+                    // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
+                    // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
+                    // 'keyof T' to a literal union type and we can't recover T from that type.
+                    type.modifiersType = instantiateType(getTypeFromTypeNode(constraintDeclaration.type), type.mapper || identityMapper);
+                }
+                else {
+                    // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
+                    // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
+                    // the modifiers type is T. Otherwise, the modifiers type is {}.
+                    var declaredType = getTypeFromMappedTypeNode(type.declaration);
+                    var constraint = getConstraintTypeFromMappedType(declaredType);
+                    var extendedConstraint = constraint && constraint.flags & 16384 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint;
+                    type.modifiersType = extendedConstraint && extendedConstraint.flags & 262144 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper || identityMapper) : emptyObjectType;
+                }
+            }
+            return type.modifiersType;
+        }
+        function isPartialMappedType(type) {
+            return getObjectFlags(type) & 32 /* Mapped */ && !!type.declaration.questionToken;
+        }
+        function isGenericMappedType(type) {
+            return getObjectFlags(type) & 32 /* Mapped */ && isGenericIndexType(getConstraintTypeFromMappedType(type));
+        }
+        function resolveStructuredTypeMembers(type) {
+            if (!type.members) {
+                if (type.flags & 32768 /* Object */) {
+                    if (type.objectFlags & 4 /* Reference */) {
+                        resolveTypeReferenceMembers(type);
+                    }
+                    else if (type.objectFlags & 3 /* ClassOrInterface */) {
+                        resolveClassOrInterfaceMembers(type);
+                    }
+                    else if (type.objectFlags & 16 /* Anonymous */) {
+                        resolveAnonymousTypeMembers(type);
+                    }
+                    else if (type.objectFlags & 32 /* Mapped */) {
+                        resolveMappedTypeMembers(type);
+                    }
+                }
+                else if (type.flags & 65536 /* Union */) {
+                    resolveUnionTypeMembers(type);
+                }
+                else if (type.flags & 131072 /* Intersection */) {
+                    resolveIntersectionTypeMembers(type);
+                }
+            }
+            return type;
+        }
+        /** Return properties of an object type or an empty array for other types */
+        function getPropertiesOfObjectType(type) {
+            if (type.flags & 32768 /* Object */) {
+                return resolveStructuredTypeMembers(type).properties;
+            }
+            return ts.emptyArray;
+        }
+        /** If the given type is an object type and that type has a property by the given name,
+         * return the symbol for that property. Otherwise return undefined.
+         */
+        function getPropertyOfObjectType(type, name) {
+            if (type.flags & 32768 /* Object */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                var symbol = resolved.members.get(name);
+                if (symbol && symbolIsValue(symbol)) {
+                    return symbol;
+                }
+            }
+        }
+        function getPropertiesOfUnionOrIntersectionType(type) {
+            if (!type.resolvedProperties) {
+                var members = ts.createSymbolTable();
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var current = _a[_i];
+                    for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) {
+                        var prop = _c[_b];
+                        if (!members.has(prop.escapedName)) {
+                            var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName);
+                            if (combinedProp) {
+                                members.set(prop.escapedName, combinedProp);
+                            }
+                        }
+                    }
+                    // The properties of a union type are those that are present in all constituent types, so
+                    // we only need to check the properties of the first type
+                    if (type.flags & 65536 /* Union */) {
+                        break;
+                    }
+                }
+                type.resolvedProperties = getNamedMembers(members);
+            }
+            return type.resolvedProperties;
+        }
+        function getPropertiesOfType(type) {
+            type = getApparentType(type);
+            return type.flags & 196608 /* UnionOrIntersection */ ?
+                getPropertiesOfUnionOrIntersectionType(type) :
+                getPropertiesOfObjectType(type);
+        }
+        function getAllPossiblePropertiesOfTypes(types) {
+            var unionType = getUnionType(types);
+            if (!(unionType.flags & 65536 /* Union */)) {
+                return getPropertiesOfType(unionType);
+            }
+            var props = ts.createSymbolTable();
+            for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
+                var memberType = types_2[_i];
+                for (var _a = 0, _b = getPropertiesOfType(memberType); _a < _b.length; _a++) {
+                    var escapedName = _b[_a].escapedName;
+                    if (!props.has(escapedName)) {
+                        props.set(escapedName, createUnionOrIntersectionProperty(unionType, escapedName));
+                    }
+                }
+            }
+            return ts.arrayFrom(props.values());
+        }
+        function getConstraintOfType(type) {
+            return type.flags & 16384 /* TypeParameter */ ? getConstraintOfTypeParameter(type) :
+                type.flags & 524288 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) :
+                    getBaseConstraintOfType(type);
+        }
+        function getConstraintOfTypeParameter(typeParameter) {
+            return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
+        }
+        function getConstraintOfIndexedAccess(type) {
+            var transformed = getTransformedIndexedAccessType(type);
+            if (transformed) {
+                return transformed;
+            }
+            var baseObjectType = getBaseConstraintOfType(type.objectType);
+            var baseIndexType = getBaseConstraintOfType(type.indexType);
+            return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined;
+        }
+        function getBaseConstraintOfType(type) {
+            if (type.flags & (540672 /* TypeVariable */ | 196608 /* UnionOrIntersection */)) {
+                var constraint = getResolvedBaseConstraint(type);
+                if (constraint !== noConstraintType && constraint !== circularConstraintType) {
+                    return constraint;
+                }
+            }
+            else if (type.flags & 262144 /* Index */) {
+                return stringType;
+            }
+            return undefined;
+        }
+        function hasNonCircularBaseConstraint(type) {
+            return getResolvedBaseConstraint(type) !== circularConstraintType;
+        }
+        /**
+         * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the
+         * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint
+         * circularly references the type variable.
+         */
+        function getResolvedBaseConstraint(type) {
+            var typeStack;
+            var circular;
+            if (!type.resolvedBaseConstraint) {
+                typeStack = [];
+                var constraint = getBaseConstraint(type);
+                type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type);
+            }
+            return type.resolvedBaseConstraint;
+            function getBaseConstraint(t) {
+                if (ts.contains(typeStack, t)) {
+                    circular = true;
+                    return undefined;
+                }
+                typeStack.push(t);
+                var result = computeBaseConstraint(t);
+                typeStack.pop();
+                return result;
+            }
+            function computeBaseConstraint(t) {
+                if (t.flags & 16384 /* TypeParameter */) {
+                    var constraint = getConstraintFromTypeParameter(t);
+                    return t.isThisType ? constraint :
+                        constraint ? getBaseConstraint(constraint) : undefined;
+                }
+                if (t.flags & 196608 /* UnionOrIntersection */) {
+                    var types = t.types;
+                    var baseTypes = [];
+                    for (var _i = 0, types_3 = types; _i < types_3.length; _i++) {
+                        var type_2 = types_3[_i];
+                        var baseType = getBaseConstraint(type_2);
+                        if (baseType) {
+                            baseTypes.push(baseType);
+                        }
+                    }
+                    return t.flags & 65536 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) :
+                        t.flags & 131072 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) :
+                            undefined;
+                }
+                if (t.flags & 262144 /* Index */) {
+                    return stringType;
+                }
+                if (t.flags & 524288 /* IndexedAccess */) {
+                    var transformed = getTransformedIndexedAccessType(t);
+                    if (transformed) {
+                        return getBaseConstraint(transformed);
+                    }
+                    var baseObjectType = getBaseConstraint(t.objectType);
+                    var baseIndexType = getBaseConstraint(t.indexType);
+                    var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined;
+                    return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined;
+                }
+                if (isGenericMappedType(t)) {
+                    return emptyObjectType;
+                }
+                return t;
+            }
+        }
+        function getApparentTypeOfIntersectionType(type) {
+            return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
+        }
+        function getResolvedTypeParameterDefault(typeParameter) {
+            if (!typeParameter.default) {
+                if (typeParameter.target) {
+                    var targetDefault = getResolvedTypeParameterDefault(typeParameter.target);
+                    typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
+                }
+                else {
+                    // To block recursion, set the initial value to the resolvingDefaultType.
+                    typeParameter.default = resolvingDefaultType;
+                    var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; });
+                    var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
+                    if (typeParameter.default === resolvingDefaultType) {
+                        // If we have not been called recursively, set the correct default type.
+                        typeParameter.default = defaultType;
+                    }
+                }
+            }
+            else if (typeParameter.default === resolvingDefaultType) {
+                // If we are called recursively for this type parameter, mark the default as circular.
+                typeParameter.default = circularConstraintType;
+            }
+            return typeParameter.default;
+        }
+        /**
+         * Gets the default type for a type parameter.
+         *
+         * If the type parameter is the result of an instantiation, this gets the instantiated
+         * default type of its target. If the type parameter has no default type or the default is
+         * circular, `undefined` is returned.
+         */
+        function getDefaultFromTypeParameter(typeParameter) {
+            var defaultType = getResolvedTypeParameterDefault(typeParameter);
+            return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined;
+        }
+        function hasNonCircularTypeParameterDefault(typeParameter) {
+            return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType;
+        }
+        /**
+         * Indicates whether the declaration of a typeParameter has a default type.
+         */
+        function hasTypeParameterDefault(typeParameter) {
+            return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }));
+        }
+        /**
+         * For a type parameter, return the base constraint of the type parameter. For the string, number,
+         * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
+         * type itself. Note that the apparent type of a union type is the union type itself.
+         */
+        function getApparentType(type) {
+            var t = type.flags & 540672 /* TypeVariable */ ? getBaseConstraintOfType(type) || emptyObjectType : type;
+            return t.flags & 131072 /* Intersection */ ? getApparentTypeOfIntersectionType(t) :
+                t.flags & 262178 /* StringLike */ ? globalStringType :
+                    t.flags & 84 /* NumberLike */ ? globalNumberType :
+                        t.flags & 136 /* BooleanLike */ ? globalBooleanType :
+                            t.flags & 512 /* ESSymbol */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) :
+                                t.flags & 16777216 /* NonPrimitive */ ? emptyObjectType :
+                                    t;
+        }
+        function createUnionOrIntersectionProperty(containingType, name) {
+            var props;
+            var types = containingType.types;
+            var isUnion = containingType.flags & 65536 /* Union */;
+            var excludeModifiers = isUnion ? 24 /* NonPublicAccessibilityModifier */ : 0;
+            // Flags we want to propagate to the result if they exist in all source symbols
+            var commonFlags = isUnion ? 0 /* None */ : 16777216 /* Optional */;
+            var syntheticFlag = 4 /* SyntheticMethod */;
+            var checkFlags = 0;
+            for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
+                var current = types_4[_i];
+                var type = getApparentType(current);
+                if (type !== unknownType) {
+                    var prop = getPropertyOfType(type, name);
+                    var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0;
+                    if (prop && !(modifiers & excludeModifiers)) {
+                        commonFlags &= prop.flags;
+                        props = ts.appendIfUnique(props, prop);
+                        checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) |
+                            (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 64 /* ContainsPublic */ : 0) |
+                            (modifiers & 16 /* Protected */ ? 128 /* ContainsProtected */ : 0) |
+                            (modifiers & 8 /* Private */ ? 256 /* ContainsPrivate */ : 0) |
+                            (modifiers & 32 /* Static */ ? 512 /* ContainsStatic */ : 0);
+                        if (!isMethodLike(prop)) {
+                            syntheticFlag = 2 /* SyntheticProperty */;
+                        }
+                    }
+                    else if (isUnion) {
+                        checkFlags |= 16 /* Partial */;
+                    }
+                }
+            }
+            if (!props) {
+                return undefined;
+            }
+            if (props.length === 1 && !(checkFlags & 16 /* Partial */)) {
+                return props[0];
+            }
+            var propTypes = [];
+            var declarations = [];
+            var commonType = undefined;
+            for (var _a = 0, props_1 = props; _a < props_1.length; _a++) {
+                var prop = props_1[_a];
+                if (prop.declarations) {
+                    ts.addRange(declarations, prop.declarations);
+                }
+                var type = getTypeOfSymbol(prop);
+                if (!commonType) {
+                    commonType = type;
+                }
+                else if (type !== commonType) {
+                    checkFlags |= 32 /* HasNonUniformType */;
+                }
+                propTypes.push(type);
+            }
+            var result = createSymbol(4 /* Property */ | commonFlags, name);
+            result.checkFlags = syntheticFlag | checkFlags;
+            result.containingType = containingType;
+            result.declarations = declarations;
+            result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
+            return result;
+        }
+        // Return the symbol for a given property in a union or intersection type, or undefined if the property
+        // does not exist in any constituent type. Note that the returned property may only be present in some
+        // constituents, in which case the isPartial flag is set when the containing type is union type. We need
+        // these partial properties when identifying discriminant properties, but otherwise they are filtered out
+        // and do not appear to be present in the union type.
+        function getUnionOrIntersectionProperty(type, name) {
+            var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable());
+            var property = properties.get(name);
+            if (!property) {
+                property = createUnionOrIntersectionProperty(type, name);
+                if (property) {
+                    properties.set(name, property);
+                }
+            }
+            return property;
+        }
+        function getPropertyOfUnionOrIntersectionType(type, name) {
+            var property = getUnionOrIntersectionProperty(type, name);
+            // We need to filter out partial properties in union types
+            return property && !(ts.getCheckFlags(property) & 16 /* Partial */) ? property : undefined;
+        }
+        /**
+         * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
+         * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
+         * Object and Function as appropriate.
+         *
+         * @param type a type to look up property from
+         * @param name a name of property to look up in a given type
+         */
+        function getPropertyOfType(type, name) {
+            type = getApparentType(type);
+            if (type.flags & 32768 /* Object */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                var symbol = resolved.members.get(name);
+                if (symbol && symbolIsValue(symbol)) {
+                    return symbol;
+                }
+                if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
+                    var symbol_1 = getPropertyOfObjectType(globalFunctionType, name);
+                    if (symbol_1) {
+                        return symbol_1;
+                    }
+                }
+                return getPropertyOfObjectType(globalObjectType, name);
+            }
+            if (type.flags & 196608 /* UnionOrIntersection */) {
+                return getPropertyOfUnionOrIntersectionType(type, name);
+            }
+            return undefined;
+        }
+        function getSignaturesOfStructuredType(type, kind) {
+            if (type.flags & 229376 /* StructuredType */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
+            }
+            return ts.emptyArray;
+        }
+        /**
+         * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
+         * maps primitive types and type parameters are to their apparent types.
+         */
+        function getSignaturesOfType(type, kind) {
+            return getSignaturesOfStructuredType(getApparentType(type), kind);
+        }
+        function getIndexInfoOfStructuredType(type, kind) {
+            if (type.flags & 229376 /* StructuredType */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo;
+            }
+        }
+        function getIndexTypeOfStructuredType(type, kind) {
+            var info = getIndexInfoOfStructuredType(type, kind);
+            return info && info.type;
+        }
+        // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
+        // maps primitive types and type parameters are to their apparent types.
+        function getIndexInfoOfType(type, kind) {
+            return getIndexInfoOfStructuredType(getApparentType(type), kind);
+        }
+        // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
+        // maps primitive types and type parameters are to their apparent types.
+        function getIndexTypeOfType(type, kind) {
+            return getIndexTypeOfStructuredType(getApparentType(type), kind);
+        }
+        function getImplicitIndexTypeOfType(type, kind) {
+            if (isObjectTypeWithInferableIndex(type)) {
+                var propTypes = [];
+                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
+                        propTypes.push(getTypeOfSymbol(prop));
+                    }
+                }
+                if (propTypes.length) {
+                    return getUnionType(propTypes, /*subtypeReduction*/ true);
+                }
+            }
+            return undefined;
+        }
+        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
+        // type checking functions).
+        function getTypeParametersFromDeclaration(declaration) {
+            var result;
+            ts.forEach(ts.getEffectiveTypeParameterDeclarations(declaration), function (node) {
+                var tp = getDeclaredTypeOfTypeParameter(node.symbol);
+                result = ts.appendIfUnique(result, tp);
+            });
+            return result;
+        }
+        function symbolsToArray(symbols) {
+            var result = [];
+            symbols.forEach(function (symbol, id) {
+                if (!isReservedMemberName(id)) {
+                    result.push(symbol);
+                }
+            });
+            return result;
+        }
+        function isJSDocOptionalParameter(node) {
+            if (ts.isInJavaScriptFile(node)) {
+                if (node.type && node.type.kind === 272 /* JSDocOptionalType */) {
+                    return true;
+                }
+                var paramTags = ts.getJSDocParameterTags(node);
+                if (paramTags) {
+                    for (var _i = 0, paramTags_1 = paramTags; _i < paramTags_1.length; _i++) {
+                        var paramTag = paramTags_1[_i];
+                        if (paramTag.isBracketed) {
+                            return true;
+                        }
+                        if (paramTag.typeExpression) {
+                            return paramTag.typeExpression.type.kind === 272 /* JSDocOptionalType */;
+                        }
+                    }
+                }
+            }
+        }
+        function tryFindAmbientModule(moduleName, withAugmentations) {
+            if (ts.isExternalModuleNameRelative(moduleName)) {
+                return undefined;
+            }
+            var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
+            // merged symbol is module declaration symbol combined with all augmentations
+            return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
+        }
+        function isOptionalParameter(node) {
+            if (ts.hasQuestionToken(node) || isJSDocOptionalParameter(node)) {
+                return true;
+            }
+            if (node.initializer) {
+                var signatureDeclaration = node.parent;
+                var signature = getSignatureFromDeclaration(signatureDeclaration);
+                var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
+                ts.Debug.assert(parameterIndex >= 0);
+                return parameterIndex >= signature.minArgumentCount;
+            }
+            var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent);
+            if (iife) {
+                return !node.type &&
+                    !node.dotDotDotToken &&
+                    ts.indexOf(node.parent.parameters, node) >= iife.arguments.length;
+            }
+            return false;
+        }
+        function createTypePredicateFromTypePredicateNode(node) {
+            var parameterName = node.parameterName;
+            if (parameterName.kind === 71 /* Identifier */) {
+                return {
+                    kind: 1 /* Identifier */,
+                    parameterName: parameterName ? parameterName.escapedText : undefined,
+                    parameterIndex: parameterName ? getTypePredicateParameterIndex(node.parent.parameters, parameterName) : undefined,
+                    type: getTypeFromTypeNode(node.type)
+                };
+            }
+            else {
+                return {
+                    kind: 0 /* This */,
+                    type: getTypeFromTypeNode(node.type)
+                };
+            }
+        }
+        /**
+         * Gets the minimum number of type arguments needed to satisfy all non-optional type
+         * parameters.
+         */
+        function getMinTypeArgumentCount(typeParameters) {
+            var minTypeArgumentCount = 0;
+            if (typeParameters) {
+                for (var i = 0; i < typeParameters.length; i++) {
+                    if (!hasTypeParameterDefault(typeParameters[i])) {
+                        minTypeArgumentCount = i + 1;
+                    }
+                }
+            }
+            return minTypeArgumentCount;
+        }
+        /**
+         * Fill in default types for unsupplied type arguments. If `typeArguments` is undefined
+         * when a default type is supplied, a new array will be created and returned.
+         *
+         * @param typeArguments The supplied type arguments.
+         * @param typeParameters The requested type parameters.
+         * @param minTypeArgumentCount The minimum number of required type arguments.
+         */
+        function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScript) {
+            var numTypeParameters = ts.length(typeParameters);
+            if (numTypeParameters) {
+                var numTypeArguments = ts.length(typeArguments);
+                if ((isJavaScript || numTypeArguments >= minTypeArgumentCount) && numTypeArguments <= numTypeParameters) {
+                    if (!typeArguments) {
+                        typeArguments = [];
+                    }
+                    // Map an unsatisfied type parameter with a default type.
+                    // If a type parameter does not have a default type, or if the default type
+                    // is a forward reference, the empty object type is used.
+                    for (var i = numTypeArguments; i < numTypeParameters; i++) {
+                        typeArguments[i] = getDefaultTypeArgumentType(isJavaScript);
+                    }
+                    for (var i = numTypeArguments; i < numTypeParameters; i++) {
+                        var mapper = createTypeMapper(typeParameters, typeArguments);
+                        var defaultType = getDefaultFromTypeParameter(typeParameters[i]);
+                        typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScript);
+                    }
+                }
+            }
+            return typeArguments;
+        }
+        function getSignatureFromDeclaration(declaration) {
+            var links = getNodeLinks(declaration);
+            if (!links.resolvedSignature) {
+                var parameters = [];
+                var hasLiteralTypes = false;
+                var minArgumentCount = 0;
+                var thisParameter = undefined;
+                var hasThisParameter = void 0;
+                var iife = ts.getImmediatelyInvokedFunctionExpression(declaration);
+                var isJSConstructSignature = ts.isJSDocConstructSignature(declaration);
+                var isUntypedSignatureInJSFile = !iife && !isJSConstructSignature && ts.isInJavaScriptFile(declaration) && !ts.hasJSDocParameterTags(declaration);
+                // If this is a JSDoc construct signature, then skip the first parameter in the
+                // parameter list.  The first parameter represents the return type of the construct
+                // signature.
+                for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) {
+                    var param = declaration.parameters[i];
+                    var paramSymbol = param.symbol;
+                    // Include parameter symbol instead of property symbol in the signature
+                    if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) {
+                        var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 107455 /* Value */, undefined, undefined, /*isUse*/ false);
+                        paramSymbol = resolvedSymbol;
+                    }
+                    if (i === 0 && paramSymbol.escapedName === "this") {
+                        hasThisParameter = true;
+                        thisParameter = param.symbol;
+                    }
+                    else {
+                        parameters.push(paramSymbol);
+                    }
+                    if (param.type && param.type.kind === 173 /* LiteralType */) {
+                        hasLiteralTypes = true;
+                    }
+                    // Record a new minimum argument count if this is not an optional parameter
+                    var isOptionalParameter_1 = param.initializer || param.questionToken || param.dotDotDotToken ||
+                        iife && parameters.length > iife.arguments.length && !param.type ||
+                        isJSDocOptionalParameter(param) ||
+                        isUntypedSignatureInJSFile;
+                    if (!isOptionalParameter_1) {
+                        minArgumentCount = parameters.length;
+                    }
+                }
+                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
+                if ((declaration.kind === 153 /* GetAccessor */ || declaration.kind === 154 /* SetAccessor */) &&
+                    !ts.hasDynamicName(declaration) &&
+                    (!hasThisParameter || !thisParameter)) {
+                    var otherKind = declaration.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */;
+                    var other = ts.getDeclarationOfKind(declaration.symbol, otherKind);
+                    if (other) {
+                        thisParameter = getAnnotatedAccessorThisParameter(other);
+                    }
+                }
+                var classType = declaration.kind === 152 /* Constructor */ ?
+                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
+                    : undefined;
+                var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
+                var returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
+                var typePredicate = declaration.type && declaration.type.kind === 158 /* TypePredicate */ ?
+                    createTypePredicateFromTypePredicateNode(declaration.type) :
+                    undefined;
+                // JS functions get a free rest parameter if they reference `arguments`
+                var hasRestLikeParameter = ts.hasRestParameter(declaration);
+                if (!hasRestLikeParameter && ts.isInJavaScriptFile(declaration) && containsArgumentsReference(declaration)) {
+                    hasRestLikeParameter = true;
+                    var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args");
+                    syntheticArgsSymbol.type = anyArrayType;
+                    syntheticArgsSymbol.isRestParameter = true;
+                    parameters.push(syntheticArgsSymbol);
+                }
+                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
+            }
+            return links.resolvedSignature;
+        }
+        function getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType) {
+            if (isJSConstructSignature) {
+                return getTypeFromTypeNode(declaration.parameters[0].type);
+            }
+            else if (classType) {
+                return classType;
+            }
+            var typeNode = ts.getEffectiveReturnTypeNode(declaration);
+            if (typeNode) {
+                return getTypeFromTypeNode(typeNode);
+            }
+            // TypeScript 1.0 spec (April 2014):
+            // If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
+            if (declaration.kind === 153 /* GetAccessor */ && !ts.hasDynamicName(declaration)) {
+                var setter = ts.getDeclarationOfKind(declaration.symbol, 154 /* SetAccessor */);
+                return getAnnotatedAccessorType(setter);
+            }
+            if (ts.nodeIsMissing(declaration.body)) {
+                return anyType;
+            }
+        }
+        function containsArgumentsReference(declaration) {
+            var links = getNodeLinks(declaration);
+            if (links.containsArgumentsReference === undefined) {
+                if (links.flags & 8192 /* CaptureArguments */) {
+                    links.containsArgumentsReference = true;
+                }
+                else {
+                    links.containsArgumentsReference = traverse(declaration.body);
+                }
+            }
+            return links.containsArgumentsReference;
+            function traverse(node) {
+                if (!node)
+                    return false;
+                switch (node.kind) {
+                    case 71 /* Identifier */:
+                        return node.escapedText === "arguments" && ts.isPartOfExpression(node);
+                    case 149 /* PropertyDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        return node.name.kind === 144 /* ComputedPropertyName */
+                            && traverse(node.name);
+                    default:
+                        return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && ts.forEachChild(node, traverse);
+                }
+            }
+        }
+        function getSignaturesOfSymbol(symbol) {
+            if (!symbol)
+                return ts.emptyArray;
+            var result = [];
+            for (var i = 0; i < symbol.declarations.length; i++) {
+                var node = symbol.declarations[i];
+                switch (node.kind) {
+                    case 160 /* FunctionType */:
+                    case 161 /* ConstructorType */:
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    case 152 /* Constructor */:
+                    case 155 /* CallSignature */:
+                    case 156 /* ConstructSignature */:
+                    case 157 /* IndexSignature */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                    case 273 /* JSDocFunctionType */:
+                        // Don't include signature if node is the implementation of an overloaded function. A node is considered
+                        // an implementation node if it has a body and the previous node is of the same kind and immediately
+                        // precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
+                        if (i > 0 && node.body) {
+                            var previous = symbol.declarations[i - 1];
+                            if (node.parent === previous.parent && node.kind === previous.kind && node.pos === previous.end) {
+                                break;
+                            }
+                        }
+                        result.push(getSignatureFromDeclaration(node));
+                }
+            }
+            return result;
+        }
+        function resolveExternalModuleTypeByLiteral(name) {
+            var moduleSym = resolveExternalModuleName(name, name);
+            if (moduleSym) {
+                var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+                if (resolvedModuleSymbol) {
+                    return getTypeOfSymbol(resolvedModuleSymbol);
+                }
+            }
+            return anyType;
+        }
+        function getThisTypeOfSignature(signature) {
+            if (signature.thisParameter) {
+                return getTypeOfSymbol(signature.thisParameter);
+            }
+        }
+        function getReturnTypeOfSignature(signature) {
+            if (!signature.resolvedReturnType) {
+                if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
+                    return unknownType;
+                }
+                var type = void 0;
+                if (signature.target) {
+                    type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper);
+                }
+                else if (signature.unionSignatures) {
+                    type = getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
+                }
+                else {
+                    type = getReturnTypeFromBody(signature.declaration);
+                }
+                if (!popTypeResolution()) {
+                    type = anyType;
+                    if (noImplicitAny) {
+                        var declaration = signature.declaration;
+                        var name = ts.getNameOfDeclaration(declaration);
+                        if (name) {
+                            error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name));
+                        }
+                        else {
+                            error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
+                        }
+                    }
+                }
+                signature.resolvedReturnType = type;
+            }
+            return signature.resolvedReturnType;
+        }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
+        }
+        function getRestTypeOfSignature(signature) {
+            if (signature.hasRestParameter) {
+                var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
+                if (getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType) {
+                    return type.typeArguments[0];
+                }
+            }
+            return anyType;
+        }
+        function getSignatureInstantiation(signature, typeArguments, isJavascript) {
+            typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript);
+            var instantiations = signature.instantiations || (signature.instantiations = ts.createMap());
+            var id = getTypeListId(typeArguments);
+            var instantiation = instantiations.get(id);
+            if (!instantiation) {
+                instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments));
+            }
+            return instantiation;
+        }
+        function createSignatureInstantiation(signature, typeArguments) {
+            return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
+        }
+        function getErasedSignature(signature) {
+            return signature.typeParameters ?
+                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
+                signature;
+        }
+        function createErasedSignature(signature) {
+            // Create an instantiation of the signature where all type arguments are the any type.
+            return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
+        }
+        function getCanonicalSignature(signature) {
+            return signature.typeParameters ?
+                signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
+                signature;
+        }
+        function createCanonicalSignature(signature) {
+            // Create an instantiation of the signature where each unconstrained type parameter is replaced with
+            // its original. When a generic class or interface is instantiated, each generic method in the class or
+            // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
+            // where different generations of the same type parameter are in scope). This leads to a lot of new type
+            // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
+            // that uses the original type identities for all unconstrained type parameters.
+            return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJavaScriptFile(signature.declaration));
+        }
+        function getOrCreateTypeFromSignature(signature) {
+            // There are two ways to declare a construct signature, one is by declaring a class constructor
+            // using the constructor keyword, and the other is declaring a bare construct signature in an
+            // object type literal or interface (using the new keyword). Each way of declaring a constructor
+            // will result in a different declaration kind.
+            if (!signature.isolatedSignatureType) {
+                var isConstructor = signature.declaration.kind === 152 /* Constructor */ || signature.declaration.kind === 156 /* ConstructSignature */;
+                var type = createObjectType(16 /* Anonymous */);
+                type.members = emptySymbols;
+                type.properties = ts.emptyArray;
+                type.callSignatures = !isConstructor ? [signature] : ts.emptyArray;
+                type.constructSignatures = isConstructor ? [signature] : ts.emptyArray;
+                signature.isolatedSignatureType = type;
+            }
+            return signature.isolatedSignatureType;
+        }
+        function getIndexSymbol(symbol) {
+            return symbol.members.get("__index" /* Index */);
+        }
+        function getIndexDeclarationOfSymbol(symbol, kind) {
+            var syntaxKind = kind === 1 /* Number */ ? 133 /* NumberKeyword */ : 136 /* StringKeyword */;
+            var indexSymbol = getIndexSymbol(symbol);
+            if (indexSymbol) {
+                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    var node = decl;
+                    if (node.parameters.length === 1) {
+                        var parameter = node.parameters[0];
+                        if (parameter && parameter.type && parameter.type.kind === syntaxKind) {
+                            return node;
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        function createIndexInfo(type, isReadonly, declaration) {
+            return { type: type, isReadonly: isReadonly, declaration: declaration };
+        }
+        function getIndexInfoOfSymbol(symbol, kind) {
+            var declaration = getIndexDeclarationOfSymbol(symbol, kind);
+            if (declaration) {
+                return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration);
+            }
+            return undefined;
+        }
+        function getConstraintDeclaration(type) {
+            return type.symbol && ts.getDeclarationOfKind(type.symbol, 145 /* TypeParameter */).constraint;
+        }
+        function getConstraintFromTypeParameter(typeParameter) {
+            if (!typeParameter.constraint) {
+                if (typeParameter.target) {
+                    var targetConstraint = getConstraintOfTypeParameter(typeParameter.target);
+                    typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType;
+                }
+                else {
+                    var constraintDeclaration = getConstraintDeclaration(typeParameter);
+                    typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : noConstraintType;
+                }
+            }
+            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
+        }
+        function getParentSymbolOfTypeParameter(typeParameter) {
+            return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 145 /* TypeParameter */).parent);
+        }
+        function getTypeListId(types) {
+            var result = "";
+            if (types) {
+                var length_4 = types.length;
+                var i = 0;
+                while (i < length_4) {
+                    var startId = types[i].id;
+                    var count = 1;
+                    while (i + count < length_4 && types[i + count].id === startId + count) {
+                        count++;
+                    }
+                    if (result.length) {
+                        result += ",";
+                    }
+                    result += startId;
+                    if (count > 1) {
+                        result += ":" + count;
+                    }
+                    i += count;
+                }
+            }
+            return result;
+        }
+        // This function is used to propagate certain flags when creating new object type references and union types.
+        // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
+        // of an object literal or the anyFunctionType. This is because there are operations in the type checker
+        // that care about the presence of such types at arbitrary depth in a containing type.
+        function getPropagatingFlagsOfTypes(types, excludeKinds) {
+            var result = 0;
+            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
+                var type = types_5[_i];
+                if (!(type.flags & excludeKinds)) {
+                    result |= type.flags;
+                }
+            }
+            return result & 14680064 /* PropagatingFlags */;
+        }
+        function createTypeReference(target, typeArguments) {
+            var id = getTypeListId(typeArguments);
+            var type = target.instantiations.get(id);
+            if (!type) {
+                type = createObjectType(4 /* Reference */, target.symbol);
+                target.instantiations.set(id, type);
+                type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
+                type.target = target;
+                type.typeArguments = typeArguments;
+            }
+            return type;
+        }
+        function cloneTypeReference(source) {
+            var type = createType(source.flags);
+            type.symbol = source.symbol;
+            type.objectFlags = source.objectFlags;
+            type.target = source.target;
+            type.typeArguments = source.typeArguments;
+            return type;
+        }
+        function getTypeReferenceArity(type) {
+            return ts.length(type.target.typeParameters);
+        }
+        /**
+         * Get type from type-reference that reference to class or interface
+         */
+        function getTypeFromClassOrInterfaceReference(node, symbol, typeArgs) {
+            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
+            var typeParameters = type.localTypeParameters;
+            if (typeParameters) {
+                var numTypeArguments = ts.length(node.typeArguments);
+                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
+                var isJavascript = ts.isInJavaScriptFile(node);
+                if (!isJavascript && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
+                    error(node, minTypeArgumentCount === typeParameters.length
+                        ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
+                        : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */), minTypeArgumentCount, typeParameters.length);
+                    return unknownType;
+                }
+                // In a type reference, the outer type parameters of the referenced class or interface are automatically
+                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
+                // of the class or interface.
+                var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJavascript));
+                return createTypeReference(type, typeArguments);
+            }
+            if (node.typeArguments) {
+                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
+                return unknownType;
+            }
+            return type;
+        }
+        function getTypeAliasInstantiation(symbol, typeArguments) {
+            var type = getDeclaredTypeOfSymbol(symbol);
+            var links = getSymbolLinks(symbol);
+            var typeParameters = links.typeParameters;
+            var id = getTypeListId(typeArguments);
+            var instantiation = links.instantiations.get(id);
+            if (!instantiation) {
+                links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJavaScriptFile(symbol.valueDeclaration)))));
+            }
+            return instantiation;
+        }
+        /**
+         * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
+         * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
+         * declared type. Instantiations are cached using the type identities of the type arguments as the key.
+         */
+        function getTypeFromTypeAliasReference(node, symbol, typeArguments) {
+            var type = getDeclaredTypeOfSymbol(symbol);
+            var typeParameters = getSymbolLinks(symbol).typeParameters;
+            if (typeParameters) {
+                var numTypeArguments = ts.length(node.typeArguments);
+                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
+                if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
+                    error(node, minTypeArgumentCount === typeParameters.length
+                        ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
+                        : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length);
+                    return unknownType;
+                }
+                return getTypeAliasInstantiation(symbol, typeArguments);
+            }
+            if (node.typeArguments) {
+                error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
+                return unknownType;
+            }
+            return type;
+        }
+        function getTypeReferenceName(node) {
+            switch (node.kind) {
+                case 159 /* TypeReference */:
+                    return node.typeName;
+                case 201 /* ExpressionWithTypeArguments */:
+                    // We only support expressions that are simple qualified names. For other
+                    // expressions this produces undefined.
+                    var expr = node.expression;
+                    if (ts.isEntityNameExpression(expr)) {
+                        return expr;
+                    }
+            }
+            return undefined;
+        }
+        function resolveTypeReferenceName(typeReferenceName, meaning) {
+            if (!typeReferenceName) {
+                return unknownSymbol;
+            }
+            return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
+        }
+        function getTypeReferenceType(node, symbol) {
+            var typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
+            if (symbol === unknownSymbol) {
+                return unknownType;
+            }
+            var type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
+            if (type) {
+                return type;
+            }
+            // Get type from reference to named type that cannot be generic (enum or type parameter)
+            var res = tryGetDeclaredTypeOfSymbol(symbol);
+            if (res !== undefined) {
+                if (typeArguments) {
+                    error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
+                    return unknownType;
+                }
+                return res;
+            }
+            if (!(symbol.flags & 107455 /* Value */ && isJSDocTypeReference(node))) {
+                return unknownType;
+            }
+            // A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
+            // the symbol is a constructor function, return the inferred class type; otherwise,
+            // the type of this reference is just the type of the value we resolved to.
+            var valueType = getTypeOfSymbol(symbol);
+            if (valueType.symbol && !isInferredClassType(valueType)) {
+                var referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
+                if (referenceType) {
+                    return referenceType;
+                }
+            }
+            // Resolve the type reference as a Type for the purpose of reporting errors.
+            resolveTypeReferenceName(getTypeReferenceName(node), 793064 /* Type */);
+            return valueType;
+        }
+        function getTypeReferenceTypeWorker(node, symbol, typeArguments) {
+            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
+                return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
+            }
+            if (symbol.flags & 524288 /* TypeAlias */) {
+                return getTypeFromTypeAliasReference(node, symbol, typeArguments);
+            }
+            if (symbol.flags & 16 /* Function */ &&
+                isJSDocTypeReference(node) &&
+                (symbol.members || ts.getJSDocClassTag(symbol.valueDeclaration))) {
+                return getInferredClassType(symbol);
+            }
+        }
+        function isJSDocTypeReference(node) {
+            return node.flags & 1048576 /* JSDoc */ && node.kind === 159 /* TypeReference */;
+        }
+        function getIntendedTypeFromJSDocTypeReference(node) {
+            if (ts.isIdentifier(node.typeName)) {
+                if (node.typeName.escapedText === "Object") {
+                    if (ts.isJSDocIndexSignature(node)) {
+                        var indexed = getTypeFromTypeNode(node.typeArguments[0]);
+                        var target = getTypeFromTypeNode(node.typeArguments[1]);
+                        var index = createIndexInfo(target, /*isReadonly*/ false);
+                        return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType && index, indexed === numberType && index);
+                    }
+                    return anyType;
+                }
+                switch (node.typeName.escapedText) {
+                    case "String":
+                        return stringType;
+                    case "Number":
+                        return numberType;
+                    case "Boolean":
+                        return booleanType;
+                    case "Void":
+                        return voidType;
+                    case "Undefined":
+                        return undefinedType;
+                    case "Null":
+                        return nullType;
+                    case "Function":
+                    case "function":
+                        return globalFunctionType;
+                    case "Array":
+                    case "array":
+                        return !node.typeArguments || !node.typeArguments.length ? anyArrayType : undefined;
+                    case "Promise":
+                    case "promise":
+                        return !node.typeArguments || !node.typeArguments.length ? createPromiseType(anyType) : undefined;
+                }
+            }
+        }
+        function getTypeFromJSDocNullableTypeNode(node) {
+            var type = getTypeFromTypeNode(node.type);
+            return strictNullChecks ? getUnionType([type, nullType]) : type;
+        }
+        function getTypeFromTypeReference(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                var symbol = void 0;
+                var type = void 0;
+                var meaning = 793064 /* Type */;
+                if (isJSDocTypeReference(node)) {
+                    type = getIntendedTypeFromJSDocTypeReference(node);
+                    meaning |= 107455 /* Value */;
+                }
+                if (!type) {
+                    symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
+                    type = getTypeReferenceType(node, symbol);
+                }
+                // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
+                // type reference in checkTypeReferenceOrExpressionWithTypeArguments.
+                links.resolvedSymbol = symbol;
+                links.resolvedType = type;
+            }
+            return links.resolvedType;
+        }
+        function typeArgumentsFromTypeReferenceNode(node) {
+            return ts.map(node.typeArguments, getTypeFromTypeNode);
+        }
+        function getTypeFromTypeQueryNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                // TypeScript 1.0 spec (April 2014): 3.6.3
+                // The expression is processed as an identifier expression (section 4.3)
+                // or property access expression(section 4.10),
+                // the widened type(section 3.9) of which becomes the result.
+                links.resolvedType = getWidenedType(checkExpression(node.exprName));
+            }
+            return links.resolvedType;
+        }
+        function getTypeOfGlobalSymbol(symbol, arity) {
+            function getTypeDeclaration(symbol) {
+                var declarations = symbol.declarations;
+                for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
+                    var declaration = declarations_3[_i];
+                    switch (declaration.kind) {
+                        case 229 /* ClassDeclaration */:
+                        case 230 /* InterfaceDeclaration */:
+                        case 232 /* EnumDeclaration */:
+                            return declaration;
+                    }
+                }
+            }
+            if (!symbol) {
+                return arity ? emptyGenericType : emptyObjectType;
+            }
+            var type = getDeclaredTypeOfSymbol(symbol);
+            if (!(type.flags & 32768 /* Object */)) {
+                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol));
+                return arity ? emptyGenericType : emptyObjectType;
+            }
+            if (ts.length(type.typeParameters) !== arity) {
+                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity);
+                return arity ? emptyGenericType : emptyObjectType;
+            }
+            return type;
+        }
+        function getGlobalValueSymbol(name, reportErrors) {
+            return getGlobalSymbol(name, 107455 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined);
+        }
+        function getGlobalTypeSymbol(name, reportErrors) {
+            return getGlobalSymbol(name, 793064 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined);
+        }
+        function getGlobalSymbol(name, meaning, diagnostic) {
+            // Don't track references for global symbols anyway, so value if `isReference` is arbitrary
+            return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
+        }
+        function getGlobalType(name, arity, reportErrors) {
+            var symbol = getGlobalTypeSymbol(name, reportErrors);
+            return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
+        }
+        function getGlobalTypedPropertyDescriptorType() {
+            return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
+        }
+        function getGlobalTemplateStringsArrayType() {
+            return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
+        }
+        function getGlobalESSymbolConstructorSymbol(reportErrors) {
+            return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors));
+        }
+        function getGlobalESSymbolType(reportErrors) {
+            return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType;
+        }
+        function getGlobalPromiseType(reportErrors) {
+            return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalPromiseConstructorSymbol(reportErrors) {
+            return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors));
+        }
+        function getGlobalPromiseConstructorLikeType(reportErrors) {
+            return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType;
+        }
+        function getGlobalAsyncIterableType(reportErrors) {
+            return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalAsyncIteratorType(reportErrors) {
+            return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalAsyncIterableIteratorType(reportErrors) {
+            return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalIterableType(reportErrors) {
+            return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalIteratorType(reportErrors) {
+            return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalIterableIteratorType(reportErrors) {
+            return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
+        }
+        function getGlobalTypeOrUndefined(name, arity) {
+            if (arity === void 0) { arity = 0; }
+            var symbol = getGlobalSymbol(name, 793064 /* Type */, /*diagnostic*/ undefined);
+            return symbol && getTypeOfGlobalSymbol(symbol, arity);
+        }
+        /**
+         * Returns a type that is inside a namespace at the global scope, e.g.
+         * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
+         */
+        function getExportedTypeFromNamespace(namespace, name) {
+            var namespaceSymbol = getGlobalSymbol(namespace, 1920 /* Namespace */, /*diagnosticMessage*/ undefined);
+            var typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, 793064 /* Type */);
+            return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
+        }
+        /**
+         * Instantiates a global type that is generic with some element type, and returns that instantiation.
+         */
+        function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) {
+            return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType;
+        }
+        function createTypedPropertyDescriptorType(propertyType) {
+            return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
+        }
+        function createAsyncIterableType(iteratedType) {
+            return createTypeFromGenericGlobalType(getGlobalAsyncIterableType(/*reportErrors*/ true), [iteratedType]);
+        }
+        function createAsyncIterableIteratorType(iteratedType) {
+            return createTypeFromGenericGlobalType(getGlobalAsyncIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
+        }
+        function createIterableType(iteratedType) {
+            return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
+        }
+        function createIterableIteratorType(iteratedType) {
+            return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
+        }
+        function createArrayType(elementType) {
+            return createTypeFromGenericGlobalType(globalArrayType, [elementType]);
+        }
+        function getTypeFromArrayTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType));
+            }
+            return links.resolvedType;
+        }
+        // We represent tuple types as type references to synthesized generic interface types created by
+        // this function. The types are of the form:
+        //
+        //   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
+        //
+        // Note that the generic type created by this function has no symbol associated with it. The same
+        // is true for each of the synthesized type parameters.
+        function createTupleTypeOfArity(arity) {
+            var typeParameters = [];
+            var properties = [];
+            for (var i = 0; i < arity; i++) {
+                var typeParameter = createType(16384 /* TypeParameter */);
+                typeParameters.push(typeParameter);
+                var property = createSymbol(4 /* Property */, "" + i);
+                property.type = typeParameter;
+                properties.push(property);
+            }
+            var type = createObjectType(8 /* Tuple */ | 4 /* Reference */);
+            type.typeParameters = typeParameters;
+            type.outerTypeParameters = undefined;
+            type.localTypeParameters = typeParameters;
+            type.instantiations = ts.createMap();
+            type.instantiations.set(getTypeListId(type.typeParameters), type);
+            type.target = type;
+            type.typeArguments = type.typeParameters;
+            type.thisType = createType(16384 /* TypeParameter */);
+            type.thisType.isThisType = true;
+            type.thisType.constraint = type;
+            type.declaredProperties = properties;
+            type.declaredCallSignatures = ts.emptyArray;
+            type.declaredConstructSignatures = ts.emptyArray;
+            type.declaredStringIndexInfo = undefined;
+            type.declaredNumberIndexInfo = undefined;
+            return type;
+        }
+        function getTupleTypeOfArity(arity) {
+            return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity));
+        }
+        function createTupleType(elementTypes) {
+            return createTypeReference(getTupleTypeOfArity(elementTypes.length), elementTypes);
+        }
+        function getTypeFromTupleTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = createTupleType(ts.map(node.elementTypes, getTypeFromTypeNode));
+            }
+            return links.resolvedType;
+        }
+        function binarySearchTypes(types, type) {
+            var low = 0;
+            var high = types.length - 1;
+            var typeId = type.id;
+            while (low <= high) {
+                var middle = low + ((high - low) >> 1);
+                var id = types[middle].id;
+                if (id === typeId) {
+                    return middle;
+                }
+                else if (id > typeId) {
+                    high = middle - 1;
+                }
+                else {
+                    low = middle + 1;
+                }
+            }
+            return ~low;
+        }
+        function containsType(types, type) {
+            return binarySearchTypes(types, type) >= 0;
+        }
+        // Return true if the given intersection type contains (a) more than one unit type or (b) an object
+        // type and a nullable type (null or undefined).
+        function isEmptyIntersectionType(type) {
+            var combined = 0;
+            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                var t = _a[_i];
+                if (t.flags & 6368 /* Unit */ && combined & 6368 /* Unit */) {
+                    return true;
+                }
+                combined |= t.flags;
+                if (combined & 6144 /* Nullable */ && combined & (32768 /* Object */ | 16777216 /* NonPrimitive */)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function addTypeToUnion(typeSet, type) {
+            var flags = type.flags;
+            if (flags & 65536 /* Union */) {
+                addTypesToUnion(typeSet, type.types);
+            }
+            else if (flags & 1 /* Any */) {
+                typeSet.containsAny = true;
+            }
+            else if (!strictNullChecks && flags & 6144 /* Nullable */) {
+                if (flags & 2048 /* Undefined */)
+                    typeSet.containsUndefined = true;
+                if (flags & 4096 /* Null */)
+                    typeSet.containsNull = true;
+                if (!(flags & 2097152 /* ContainsWideningType */))
+                    typeSet.containsNonWideningType = true;
+            }
+            else if (!(flags & 8192 /* Never */ || flags & 131072 /* Intersection */ && isEmptyIntersectionType(type))) {
+                // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
+                // another form of 'never' (in that they have an empty value domain). We could in theory turn
+                // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
+                // easier to reason about their origin.
+                if (flags & 2 /* String */)
+                    typeSet.containsString = true;
+                if (flags & 4 /* Number */)
+                    typeSet.containsNumber = true;
+                if (flags & 96 /* StringOrNumberLiteral */)
+                    typeSet.containsStringOrNumberLiteral = true;
+                var len = typeSet.length;
+                var index = len && type.id > typeSet[len - 1].id ? ~len : binarySearchTypes(typeSet, type);
+                if (index < 0) {
+                    if (!(flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */ &&
+                        type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) {
+                        typeSet.splice(~index, 0, type);
+                    }
+                }
+            }
+        }
+        // Add the given types to the given type set. Order is preserved, duplicates are removed,
+        // and nested types of the given kind are flattened into the set.
+        function addTypesToUnion(typeSet, types) {
+            for (var _i = 0, types_6 = types; _i < types_6.length; _i++) {
+                var type = types_6[_i];
+                addTypeToUnion(typeSet, type);
+            }
+        }
+        function containsIdenticalType(types, type) {
+            for (var _i = 0, types_7 = types; _i < types_7.length; _i++) {
+                var t = types_7[_i];
+                if (isTypeIdenticalTo(t, type)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function isSubtypeOfAny(candidate, types) {
+            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
+                var type = types_8[_i];
+                if (candidate !== type && isTypeSubtypeOf(candidate, type)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function isSetOfLiteralsFromSameEnum(types) {
+            var first = types[0];
+            if (first.flags & 256 /* EnumLiteral */) {
+                var firstEnum = getParentOfSymbol(first.symbol);
+                for (var i = 1; i < types.length; i++) {
+                    var other = types[i];
+                    if (!(other.flags & 256 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        function removeSubtypes(types) {
+            if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) {
+                return;
+            }
+            var i = types.length;
+            while (i > 0) {
+                i--;
+                if (isSubtypeOfAny(types[i], types)) {
+                    ts.orderedRemoveItemAt(types, i);
+                }
+            }
+        }
+        function removeRedundantLiteralTypes(types) {
+            var i = types.length;
+            while (i > 0) {
+                i--;
+                var t = types[i];
+                var remove = t.flags & 32 /* StringLiteral */ && types.containsString ||
+                    t.flags & 64 /* NumberLiteral */ && types.containsNumber ||
+                    t.flags & 96 /* StringOrNumberLiteral */ && t.flags & 1048576 /* FreshLiteral */ && containsType(types, t.regularType);
+                if (remove) {
+                    ts.orderedRemoveItemAt(types, i);
+                }
+            }
+        }
+        // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
+        // flag is specified we also reduce the constituent type set to only include types that aren't subtypes
+        // of other types. Subtype reduction is expensive for large union types and is possible only when union
+        // types are known not to circularly reference themselves (as is the case with union types created by
+        // expression constructs such as array literals and the || and ?: operators). Named types can
+        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
+        // For example, "type Item = string | (() => Item" is a named type that circularly references itself.
+        function getUnionType(types, subtypeReduction, aliasSymbol, aliasTypeArguments) {
+            if (types.length === 0) {
+                return neverType;
+            }
+            if (types.length === 1) {
+                return types[0];
+            }
+            var typeSet = [];
+            addTypesToUnion(typeSet, types);
+            if (typeSet.containsAny) {
+                return anyType;
+            }
+            if (subtypeReduction) {
+                removeSubtypes(typeSet);
+            }
+            else if (typeSet.containsStringOrNumberLiteral) {
+                removeRedundantLiteralTypes(typeSet);
+            }
+            if (typeSet.length === 0) {
+                return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
+                    typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
+                        neverType;
+            }
+            return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
+        }
+        // This function assumes the constituent type list is sorted and deduplicated.
+        function getUnionTypeFromSortedList(types, aliasSymbol, aliasTypeArguments) {
+            if (types.length === 0) {
+                return neverType;
+            }
+            if (types.length === 1) {
+                return types[0];
+            }
+            var id = getTypeListId(types);
+            var type = unionTypes.get(id);
+            if (!type) {
+                var propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 6144 /* Nullable */);
+                type = createType(65536 /* Union */ | propagatedFlags);
+                unionTypes.set(id, type);
+                type.types = types;
+                /*
+                Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
+                For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
+                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
+                It's important that we create equivalent union types only once, so that's an unfortunate side effect.
+                */
+                type.aliasSymbol = aliasSymbol;
+                type.aliasTypeArguments = aliasTypeArguments;
+            }
+            return type;
+        }
+        function getTypeFromUnionTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false, getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
+            }
+            return links.resolvedType;
+        }
+        function addTypeToIntersection(typeSet, type) {
+            if (type.flags & 131072 /* Intersection */) {
+                addTypesToIntersection(typeSet, type.types);
+            }
+            else if (type.flags & 1 /* Any */) {
+                typeSet.containsAny = true;
+            }
+            else if (type.flags & 8192 /* Never */) {
+                typeSet.containsNever = true;
+            }
+            else if (getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type)) {
+                typeSet.containsEmptyObject = true;
+            }
+            else if ((strictNullChecks || !(type.flags & 6144 /* Nullable */)) && !ts.contains(typeSet, type)) {
+                if (type.flags & 32768 /* Object */) {
+                    typeSet.containsObjectType = true;
+                }
+                if (type.flags & 65536 /* Union */ && typeSet.unionIndex === undefined) {
+                    typeSet.unionIndex = typeSet.length;
+                }
+                if (!(type.flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */ &&
+                    type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) {
+                    typeSet.push(type);
+                }
+            }
+        }
+        // Add the given types to the given type set. Order is preserved, duplicates are removed,
+        // and nested types of the given kind are flattened into the set.
+        function addTypesToIntersection(typeSet, types) {
+            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
+                var type = types_9[_i];
+                addTypeToIntersection(typeSet, type);
+            }
+        }
+        // We normalize combinations of intersection and union types based on the distributive property of the '&'
+        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
+        // types with union type constituents into equivalent union types with intersection type constituents and
+        // effectively ensure that union types are always at the top level in type representations.
+        //
+        // We do not perform structural deduplication on intersection types. Intersection types are created only by the &
+        // type operator and we can't reduce those because we want to support recursive intersection types. For example,
+        // a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
+        // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
+        // for intersections of types with signatures can be deterministic.
+        function getIntersectionType(types, aliasSymbol, aliasTypeArguments) {
+            if (types.length === 0) {
+                return emptyObjectType;
+            }
+            var typeSet = [];
+            addTypesToIntersection(typeSet, types);
+            if (typeSet.containsNever) {
+                return neverType;
+            }
+            if (typeSet.containsAny) {
+                return anyType;
+            }
+            if (typeSet.containsEmptyObject && !typeSet.containsObjectType) {
+                typeSet.push(emptyObjectType);
+            }
+            if (typeSet.length === 1) {
+                return typeSet[0];
+            }
+            var unionIndex = typeSet.unionIndex;
+            if (unionIndex !== undefined) {
+                // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
+                // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
+                var unionType = typeSet[unionIndex];
+                return getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex, t)); }), 
+                /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
+            }
+            var id = getTypeListId(typeSet);
+            var type = intersectionTypes.get(id);
+            if (!type) {
+                var propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 6144 /* Nullable */);
+                type = createType(131072 /* Intersection */ | propagatedFlags);
+                intersectionTypes.set(id, type);
+                type.types = typeSet;
+                type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
+                type.aliasTypeArguments = aliasTypeArguments;
+            }
+            return type;
+        }
+        function getTypeFromIntersectionTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
+            }
+            return links.resolvedType;
+        }
+        function getIndexTypeForGenericType(type) {
+            if (!type.resolvedIndexType) {
+                type.resolvedIndexType = createType(262144 /* Index */);
+                type.resolvedIndexType.type = type;
+            }
+            return type.resolvedIndexType;
+        }
+        function getLiteralTypeFromPropertyName(prop) {
+            return ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */ || ts.startsWith(prop.escapedName, "__@") ?
+                neverType :
+                getLiteralType(ts.symbolName(prop));
+        }
+        function getLiteralTypeFromPropertyNames(type) {
+            return getUnionType(ts.map(getPropertiesOfType(type), getLiteralTypeFromPropertyName));
+        }
+        function getIndexType(type) {
+            return maybeTypeOfKind(type, 540672 /* TypeVariable */) ? getIndexTypeForGenericType(type) :
+                getObjectFlags(type) & 32 /* Mapped */ ? getConstraintTypeFromMappedType(type) :
+                    type.flags & 1 /* Any */ || getIndexInfoOfType(type, 0 /* String */) ? stringType :
+                        getLiteralTypeFromPropertyNames(type);
+        }
+        function getIndexTypeOrString(type) {
+            var indexType = getIndexType(type);
+            return indexType !== neverType ? indexType : stringType;
+        }
+        function getTypeFromTypeOperatorNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
+            }
+            return links.resolvedType;
+        }
+        function createIndexedAccessType(objectType, indexType) {
+            var type = createType(524288 /* IndexedAccess */);
+            type.objectType = objectType;
+            type.indexType = indexType;
+            return type;
+        }
+        function getPropertyTypeForIndexType(objectType, indexType, accessNode, cacheSymbol) {
+            var accessExpression = accessNode && accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode : undefined;
+            var propName = indexType.flags & 96 /* StringOrNumberLiteral */ ?
+                ts.escapeLeadingUnderscores("" + indexType.value) :
+                accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
+                    ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) :
+                    undefined;
+            if (propName !== undefined) {
+                var prop = getPropertyOfType(objectType, propName);
+                if (prop) {
+                    if (accessExpression) {
+                        if (ts.isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) {
+                            error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop));
+                            return unknownType;
+                        }
+                        if (cacheSymbol) {
+                            getNodeLinks(accessNode).resolvedSymbol = prop;
+                        }
+                    }
+                    return getTypeOfSymbol(prop);
+                }
+            }
+            if (!(indexType.flags & 6144 /* Nullable */) && isTypeAssignableToKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) {
+                if (isTypeAny(objectType)) {
+                    return anyType;
+                }
+                var indexInfo = isTypeAssignableToKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) ||
+                    getIndexInfoOfType(objectType, 0 /* String */) ||
+                    undefined;
+                if (indexInfo) {
+                    if (accessExpression && indexInfo.isReadonly && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) {
+                        error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
+                    }
+                    return indexInfo.type;
+                }
+                if (accessExpression && !isConstEnumObjectType(objectType)) {
+                    if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
+                        if (getIndexTypeOfType(objectType, 1 /* Number */)) {
+                            error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
+                        }
+                        else {
+                            error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType));
+                        }
+                    }
+                    return anyType;
+                }
+            }
+            if (accessNode) {
+                var indexNode = accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode.argumentExpression : accessNode.indexType;
+                if (indexType.flags & (32 /* StringLiteral */ | 64 /* NumberLiteral */)) {
+                    error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType));
+                }
+                else if (indexType.flags & (2 /* String */ | 4 /* Number */)) {
+                    error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
+                }
+                else {
+                    error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
+                }
+                return unknownType;
+            }
+            return anyType;
+        }
+        function isGenericObjectType(type) {
+            return type.flags & 540672 /* TypeVariable */ ? true :
+                getObjectFlags(type) & 32 /* Mapped */ ? isGenericIndexType(getConstraintTypeFromMappedType(type)) :
+                    type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericObjectType) :
+                        false;
+        }
+        function isGenericIndexType(type) {
+            return type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ? true :
+                type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericIndexType) :
+                    false;
+        }
+        // Return true if the given type is a non-generic object type with a string index signature and no
+        // other members.
+        function isStringIndexOnlyType(type) {
+            if (type.flags & 32768 /* Object */ && !isGenericMappedType(type)) {
+                var t = resolveStructuredTypeMembers(type);
+                return t.properties.length === 0 &&
+                    t.callSignatures.length === 0 && t.constructSignatures.length === 0 &&
+                    t.stringIndexInfo && !t.numberIndexInfo;
+            }
+            return false;
+        }
+        // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
+        // undefined if no transformation is possible.
+        function getTransformedIndexedAccessType(type) {
+            var objectType = type.objectType;
+            // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or
+            // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a
+            // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed
+            // access types with default property values as expressed by D.
+            if (objectType.flags & 131072 /* Intersection */ && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) {
+                var regularTypes = [];
+                var stringIndexTypes = [];
+                for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    if (isStringIndexOnlyType(t)) {
+                        stringIndexTypes.push(getIndexTypeOfType(t, 0 /* String */));
+                    }
+                    else {
+                        regularTypes.push(t);
+                    }
+                }
+                return getUnionType([
+                    getIndexedAccessType(getIntersectionType(regularTypes), type.indexType),
+                    getIntersectionType(stringIndexTypes)
+                ]);
+            }
+            // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
+            // that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
+            // construct the type Box<T[X]>.
+            if (isGenericMappedType(objectType)) {
+                var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]);
+                var objectTypeMapper = objectType.mapper;
+                var templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper;
+                return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
+            }
+            return undefined;
+        }
+        function getIndexedAccessType(objectType, indexType, accessNode) {
+            // If the index type is generic, or if the object type is generic and doesn't originate in an expression,
+            // we are performing a higher-order index access where we cannot meaningfully access the properties of the
+            // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
+            // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
+            // has always been resolved eagerly using the constraint type of 'this' at the given location.
+            if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) && isGenericObjectType(objectType)) {
+                if (objectType.flags & 1 /* Any */) {
+                    return objectType;
+                }
+                // Defer the operation by creating an indexed access type.
+                var id = objectType.id + "," + indexType.id;
+                var type = indexedAccessTypes.get(id);
+                if (!type) {
+                    indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType));
+                }
+                return type;
+            }
+            // In the following we resolve T[K] to the type of the property in T selected by K.
+            // We treat boolean as different from other unions to improve errors;
+            // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
+            var apparentObjectType = getApparentType(objectType);
+            if (indexType.flags & 65536 /* Union */ && !(indexType.flags & 8 /* Boolean */)) {
+                var propTypes = [];
+                for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    var propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false);
+                    if (propType === unknownType) {
+                        return unknownType;
+                    }
+                    propTypes.push(propType);
+                }
+                return getUnionType(propTypes);
+            }
+            return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true);
+        }
+        function getTypeFromIndexedAccessTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node);
+            }
+            return links.resolvedType;
+        }
+        function getTypeFromMappedTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                var type = createObjectType(32 /* Mapped */, node.symbol);
+                type.declaration = node;
+                type.aliasSymbol = getAliasSymbolForTypeNode(node);
+                type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
+                links.resolvedType = type;
+                // Eagerly resolve the constraint type which forces an error if the constraint type circularly
+                // references itself through one or more type aliases.
+                getConstraintTypeFromMappedType(type);
+            }
+            return links.resolvedType;
+        }
+        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                // Deferred resolution of members is handled by resolveObjectTypeMembers
+                var aliasSymbol = getAliasSymbolForTypeNode(node);
+                if (node.symbol.members.size === 0 && !aliasSymbol) {
+                    links.resolvedType = emptyTypeLiteralType;
+                }
+                else {
+                    var type = createObjectType(16 /* Anonymous */, node.symbol);
+                    type.aliasSymbol = aliasSymbol;
+                    type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
+                    if (ts.isJSDocTypeLiteral(node) && node.isArrayType) {
+                        type = createArrayType(type);
+                    }
+                    links.resolvedType = type;
+                }
+            }
+            return links.resolvedType;
+        }
+        function getAliasSymbolForTypeNode(node) {
+            return node.parent.kind === 231 /* TypeAliasDeclaration */ ? getSymbolOfNode(node.parent) : undefined;
+        }
+        function getAliasTypeArgumentsForTypeNode(node) {
+            var symbol = getAliasSymbolForTypeNode(node);
+            return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
+        }
+        /**
+         * Since the source of spread types are object literals, which are not binary,
+         * this function should be called in a left folding style, with left = previous result of getSpreadType
+         * and right = the new element to be spread.
+         */
+        function getSpreadType(left, right, symbol, propagatedFlags) {
+            if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) {
+                return anyType;
+            }
+            if (left.flags & 8192 /* Never */) {
+                return right;
+            }
+            if (right.flags & 8192 /* Never */) {
+                return left;
+            }
+            if (left.flags & 65536 /* Union */) {
+                return mapType(left, function (t) { return getSpreadType(t, right, symbol, propagatedFlags); });
+            }
+            if (right.flags & 65536 /* Union */) {
+                return mapType(right, function (t) { return getSpreadType(left, t, symbol, propagatedFlags); });
+            }
+            if (right.flags & 16777216 /* NonPrimitive */) {
+                return nonPrimitiveType;
+            }
+            if (right.flags & (136 /* BooleanLike */ | 84 /* NumberLike */ | 262178 /* StringLike */ | 272 /* EnumLike */)) {
+                return left;
+            }
+            var members = ts.createSymbolTable();
+            var skippedPrivateMembers = ts.createUnderscoreEscapedMap();
+            var stringIndexInfo;
+            var numberIndexInfo;
+            if (left === emptyObjectType) {
+                // for the first spread element, left === emptyObjectType, so take the right's string indexer
+                stringIndexInfo = getIndexInfoOfType(right, 0 /* String */);
+                numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */);
+            }
+            else {
+                stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */));
+                numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */));
+            }
+            for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) {
+                var rightProp = _a[_i];
+                // we approximate own properties as non-methods plus methods that are inside the object literal
+                var isSetterWithoutGetter = rightProp.flags & 65536 /* SetAccessor */ && !(rightProp.flags & 32768 /* GetAccessor */);
+                if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) {
+                    skippedPrivateMembers.set(rightProp.escapedName, true);
+                }
+                else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) {
+                    members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp));
+                }
+            }
+            for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) {
+                var leftProp = _c[_b];
+                if (leftProp.flags & 65536 /* SetAccessor */ && !(leftProp.flags & 32768 /* GetAccessor */)
+                    || skippedPrivateMembers.has(leftProp.escapedName)
+                    || isClassMethod(leftProp)) {
+                    continue;
+                }
+                if (members.has(leftProp.escapedName)) {
+                    var rightProp = members.get(leftProp.escapedName);
+                    var rightType = getTypeOfSymbol(rightProp);
+                    if (rightProp.flags & 16777216 /* Optional */) {
+                        var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations);
+                        var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */);
+                        var result = createSymbol(flags, leftProp.escapedName);
+                        result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 131072 /* NEUndefined */)]);
+                        result.leftSpread = leftProp;
+                        result.rightSpread = rightProp;
+                        result.declarations = declarations;
+                        members.set(leftProp.escapedName, result);
+                    }
+                }
+                else {
+                    members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp));
+                }
+            }
+            var spread = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
+            spread.flags |= propagatedFlags;
+            spread.flags |= 1048576 /* FreshLiteral */ | 4194304 /* ContainsObjectLiteral */;
+            spread.objectFlags |= 128 /* ObjectLiteral */;
+            spread.symbol = symbol;
+            return spread;
+        }
+        function getNonReadonlySymbol(prop) {
+            if (!isReadonlySymbol(prop)) {
+                return prop;
+            }
+            var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */);
+            var result = createSymbol(flags, prop.escapedName);
+            result.type = getTypeOfSymbol(prop);
+            result.declarations = prop.declarations;
+            result.syntheticOrigin = prop;
+            return result;
+        }
+        function isClassMethod(prop) {
+            return prop.flags & 8192 /* Method */ && ts.find(prop.declarations, function (decl) { return ts.isClassLike(decl.parent); });
+        }
+        function createLiteralType(flags, value, symbol) {
+            var type = createType(flags);
+            type.symbol = symbol;
+            type.value = value;
+            return type;
+        }
+        function getFreshTypeOfLiteralType(type) {
+            if (type.flags & 96 /* StringOrNumberLiteral */ && !(type.flags & 1048576 /* FreshLiteral */)) {
+                if (!type.freshType) {
+                    var freshType = createLiteralType(type.flags | 1048576 /* FreshLiteral */, type.value, type.symbol);
+                    freshType.regularType = type;
+                    type.freshType = freshType;
+                }
+                return type.freshType;
+            }
+            return type;
+        }
+        function getRegularTypeOfLiteralType(type) {
+            return type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? type.regularType : type;
+        }
+        function getLiteralType(value, enumId, symbol) {
+            // We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
+            // where NNN is the text representation of a numeric literal and SSS are the characters
+            // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
+            // EEE is a unique id for the containing enum type.
+            var qualifier = typeof value === "number" ? "#" : "@";
+            var key = enumId ? enumId + qualifier + value : qualifier + value;
+            var type = literalTypes.get(key);
+            if (!type) {
+                var flags = (typeof value === "number" ? 64 /* NumberLiteral */ : 32 /* StringLiteral */) | (enumId ? 256 /* EnumLiteral */ : 0);
+                literalTypes.set(key, type = createLiteralType(flags, value, symbol));
+            }
+            return type;
+        }
+        function getTypeFromLiteralTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
+            }
+            return links.resolvedType;
+        }
+        function getTypeFromJSDocVariadicType(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                var type = getTypeFromTypeNode(node.type);
+                links.resolvedType = type ? createArrayType(type) : unknownType;
+            }
+            return links.resolvedType;
+        }
+        function getThisType(node) {
+            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
+            var parent = container && container.parent;
+            if (parent && (ts.isClassLike(parent) || parent.kind === 230 /* InterfaceDeclaration */)) {
+                if (!ts.hasModifier(container, 32 /* Static */) &&
+                    (container.kind !== 152 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) {
+                    return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
+                }
+            }
+            error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface);
+            return unknownType;
+        }
+        function getTypeFromThisTypeNode(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                links.resolvedType = getThisType(node);
+            }
+            return links.resolvedType;
+        }
+        function getTypeFromTypeNode(node) {
+            switch (node.kind) {
+                case 119 /* AnyKeyword */:
+                case 268 /* JSDocAllType */:
+                case 269 /* JSDocUnknownType */:
+                    return anyType;
+                case 136 /* StringKeyword */:
+                    return stringType;
+                case 133 /* NumberKeyword */:
+                    return numberType;
+                case 122 /* BooleanKeyword */:
+                    return booleanType;
+                case 137 /* SymbolKeyword */:
+                    return esSymbolType;
+                case 105 /* VoidKeyword */:
+                    return voidType;
+                case 139 /* UndefinedKeyword */:
+                    return undefinedType;
+                case 95 /* NullKeyword */:
+                    return nullType;
+                case 130 /* NeverKeyword */:
+                    return neverType;
+                case 134 /* ObjectKeyword */:
+                    return node.flags & 65536 /* JavaScriptFile */ ? anyType : nonPrimitiveType;
+                case 169 /* ThisType */:
+                case 99 /* ThisKeyword */:
+                    return getTypeFromThisTypeNode(node);
+                case 173 /* LiteralType */:
+                    return getTypeFromLiteralTypeNode(node);
+                case 159 /* TypeReference */:
+                    return getTypeFromTypeReference(node);
+                case 158 /* TypePredicate */:
+                    return booleanType;
+                case 201 /* ExpressionWithTypeArguments */:
+                    return getTypeFromTypeReference(node);
+                case 162 /* TypeQuery */:
+                    return getTypeFromTypeQueryNode(node);
+                case 164 /* ArrayType */:
+                    return getTypeFromArrayTypeNode(node);
+                case 165 /* TupleType */:
+                    return getTypeFromTupleTypeNode(node);
+                case 166 /* UnionType */:
+                    return getTypeFromUnionTypeNode(node);
+                case 167 /* IntersectionType */:
+                    return getTypeFromIntersectionTypeNode(node);
+                case 270 /* JSDocNullableType */:
+                    return getTypeFromJSDocNullableTypeNode(node);
+                case 168 /* ParenthesizedType */:
+                case 271 /* JSDocNonNullableType */:
+                case 272 /* JSDocOptionalType */:
+                case 267 /* JSDocTypeExpression */:
+                    return getTypeFromTypeNode(node.type);
+                case 160 /* FunctionType */:
+                case 161 /* ConstructorType */:
+                case 163 /* TypeLiteral */:
+                case 285 /* JSDocTypeLiteral */:
+                case 273 /* JSDocFunctionType */:
+                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
+                case 170 /* TypeOperator */:
+                    return getTypeFromTypeOperatorNode(node);
+                case 171 /* IndexedAccessType */:
+                    return getTypeFromIndexedAccessTypeNode(node);
+                case 172 /* MappedType */:
+                    return getTypeFromMappedTypeNode(node);
+                // This function assumes that an identifier or qualified name is a type expression
+                // Callers should first ensure this by calling isTypeNode
+                case 71 /* Identifier */:
+                case 143 /* QualifiedName */:
+                    var symbol = getSymbolAtLocation(node);
+                    return symbol && getDeclaredTypeOfSymbol(symbol);
+                case 274 /* JSDocVariadicType */:
+                    return getTypeFromJSDocVariadicType(node);
+                default:
+                    return unknownType;
+            }
+        }
+        function instantiateList(items, mapper, instantiator) {
+            if (items && items.length) {
+                var result = [];
+                for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
+                    var v = items_1[_i];
+                    result.push(instantiator(v, mapper));
+                }
+                return result;
+            }
+            return items;
+        }
+        function instantiateTypes(types, mapper) {
+            return instantiateList(types, mapper, instantiateType);
+        }
+        function instantiateSignatures(signatures, mapper) {
+            return instantiateList(signatures, mapper, instantiateSignature);
+        }
+        function makeUnaryTypeMapper(source, target) {
+            return function (t) { return t === source ? target : t; };
+        }
+        function makeBinaryTypeMapper(source1, target1, source2, target2) {
+            return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; };
+        }
+        function makeArrayTypeMapper(sources, targets) {
+            return function (t) {
+                for (var i = 0; i < sources.length; i++) {
+                    if (t === sources[i]) {
+                        return targets ? targets[i] : anyType;
+                    }
+                }
+                return t;
+            };
+        }
+        function createTypeMapper(sources, targets) {
+            ts.Debug.assert(targets === undefined || sources.length === targets.length);
+            return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
+                sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
+                    makeArrayTypeMapper(sources, targets);
+        }
+        function createTypeEraser(sources) {
+            return createTypeMapper(sources, /*targets*/ undefined);
+        }
+        /**
+         * Maps forward-references to later types parameters to the empty object type.
+         * This is used during inference when instantiating type parameter defaults.
+         */
+        function createBackreferenceMapper(typeParameters, index) {
+            return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; };
+        }
+        function isInferenceContext(mapper) {
+            return !!mapper.signature;
+        }
+        function cloneTypeMapper(mapper) {
+            return mapper && isInferenceContext(mapper) ?
+                createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.compareTypes, mapper.inferences) :
+                mapper;
+        }
+        function combineTypeMappers(mapper1, mapper2) {
+            return function (t) { return instantiateType(mapper1(t), mapper2); };
+        }
+        function createReplacementMapper(source, target, baseMapper) {
+            return function (t) { return t === source ? target : baseMapper(t); };
+        }
+        function cloneTypeParameter(typeParameter) {
+            var result = createType(16384 /* TypeParameter */);
+            result.symbol = typeParameter.symbol;
+            result.target = typeParameter;
+            return result;
+        }
+        function cloneTypePredicate(predicate, mapper) {
+            if (ts.isIdentifierTypePredicate(predicate)) {
+                return {
+                    kind: 1 /* Identifier */,
+                    parameterName: predicate.parameterName,
+                    parameterIndex: predicate.parameterIndex,
+                    type: instantiateType(predicate.type, mapper)
+                };
+            }
+            else {
+                return {
+                    kind: 0 /* This */,
+                    type: instantiateType(predicate.type, mapper)
+                };
+            }
+        }
+        function instantiateSignature(signature, mapper, eraseTypeParameters) {
+            var freshTypeParameters;
+            var freshTypePredicate;
+            if (signature.typeParameters && !eraseTypeParameters) {
+                // First create a fresh set of type parameters, then include a mapping from the old to the
+                // new type parameters in the mapper function. Finally store this mapper in the new type
+                // parameters such that we can use it when instantiating constraints.
+                freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter);
+                mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
+                for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) {
+                    var tp = freshTypeParameters_1[_i];
+                    tp.mapper = mapper;
+                }
+            }
+            if (signature.typePredicate) {
+                freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
+            }
+            var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), 
+            /*resolvedReturnType*/ undefined, freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
+            result.target = signature;
+            result.mapper = mapper;
+            return result;
+        }
+        function instantiateSymbol(symbol, mapper) {
+            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
+                var links = getSymbolLinks(symbol);
+                // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
+                // type mappers. This ensures that original type identities are properly preserved and that aliases
+                // always reference a non-aliases.
+                symbol = links.target;
+                mapper = combineTypeMappers(links.mapper, mapper);
+            }
+            // Keep the flags from the symbol we're instantiating.  Mark that is instantiated, and
+            // also transient so that we can just store data on it directly.
+            var result = createSymbol(symbol.flags, symbol.escapedName);
+            result.checkFlags = 1 /* Instantiated */;
+            result.declarations = symbol.declarations;
+            result.parent = symbol.parent;
+            result.target = symbol;
+            result.mapper = mapper;
+            if (symbol.valueDeclaration) {
+                result.valueDeclaration = symbol.valueDeclaration;
+            }
+            if (symbol.isRestParameter) {
+                result.isRestParameter = symbol.isRestParameter;
+            }
+            return result;
+        }
+        function getAnonymousTypeInstantiation(type, mapper) {
+            var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type;
+            var symbol = target.symbol;
+            var links = getSymbolLinks(symbol);
+            var typeParameters = links.typeParameters;
+            if (!typeParameters) {
+                // The first time an anonymous type is instantiated we compute and store a list of the type
+                // parameters that are in scope (and therefore potentially referenced). For type literals that
+                // aren't the right hand side of a generic type alias declaration we optimize by reducing the
+                // set of type parameters to those that are possibly referenced in the literal.
+                var declaration_1 = symbol.declarations[0];
+                var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true) || ts.emptyArray;
+                typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ?
+                    ts.filter(outerTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) :
+                    outerTypeParameters;
+                links.typeParameters = typeParameters;
+                if (typeParameters.length) {
+                    links.instantiations = ts.createMap();
+                    links.instantiations.set(getTypeListId(typeParameters), target);
+                }
+            }
+            if (typeParameters.length) {
+                // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
+                // mapper to the type parameters to produce the effective list of type arguments, and compute the
+                // instantiation cache key from the type IDs of the type arguments.
+                var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper;
+                var typeArguments = ts.map(typeParameters, combinedMapper);
+                var id = getTypeListId(typeArguments);
+                var result = links.instantiations.get(id);
+                if (!result) {
+                    var newMapper = createTypeMapper(typeParameters, typeArguments);
+                    result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper);
+                    links.instantiations.set(id, result);
+                }
+                return result;
+            }
+            return type;
+        }
+        function isTypeParameterPossiblyReferenced(tp, node) {
+            // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks
+            // between the node and the type parameter declaration, if the node contains actual references to the
+            // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
+            if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
+                var container_1 = tp.symbol.declarations[0].parent;
+                if (ts.findAncestor(node, function (n) { return n.kind === 207 /* Block */ ? "quit" : n === container_1; })) {
+                    return ts.forEachChild(node, containsReference);
+                }
+            }
+            return true;
+            function containsReference(node) {
+                switch (node.kind) {
+                    case 169 /* ThisType */:
+                        return tp.isThisType;
+                    case 71 /* Identifier */:
+                        return !tp.isThisType && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp;
+                    case 162 /* TypeQuery */:
+                        return true;
+                }
+                return ts.forEachChild(node, containsReference);
+            }
+        }
+        function instantiateMappedType(type, mapper) {
+            // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some
+            // type variable T. If so, the mapped type is distributive over a union type and when T is instantiated
+            // to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for
+            // homomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
+            // union type A | undefined, we produce { [P in keyof A]: X } | undefined.
+            var constraintType = getConstraintTypeFromMappedType(type);
+            if (constraintType.flags & 262144 /* Index */) {
+                var typeVariable_1 = constraintType.type;
+                if (typeVariable_1.flags & 16384 /* TypeParameter */) {
+                    var mappedTypeVariable = instantiateType(typeVariable_1, mapper);
+                    if (typeVariable_1 !== mappedTypeVariable) {
+                        return mapType(mappedTypeVariable, function (t) {
+                            if (isMappableType(t)) {
+                                return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper));
+                            }
+                            return t;
+                        });
+                    }
+                }
+            }
+            return instantiateAnonymousType(type, mapper);
+        }
+        function isMappableType(type) {
+            return type.flags & (1 /* Any */ | 16384 /* TypeParameter */ | 32768 /* Object */ | 131072 /* Intersection */ | 524288 /* IndexedAccess */);
+        }
+        function instantiateAnonymousType(type, mapper) {
+            var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol);
+            if (type.objectFlags & 32 /* Mapped */) {
+                result.declaration = type.declaration;
+            }
+            result.target = type;
+            result.mapper = mapper;
+            result.aliasSymbol = type.aliasSymbol;
+            result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
+            return result;
+        }
+        function instantiateType(type, mapper) {
+            if (type && mapper !== identityMapper) {
+                if (type.flags & 16384 /* TypeParameter */) {
+                    return mapper(type);
+                }
+                if (type.flags & 32768 /* Object */) {
+                    if (type.objectFlags & 16 /* Anonymous */) {
+                        // If the anonymous type originates in a declaration of a function, method, class, or
+                        // interface, in an object type literal, or in an object literal expression, we may need
+                        // to instantiate the type because it might reference a type parameter.
+                        return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ?
+                            getAnonymousTypeInstantiation(type, mapper) : type;
+                    }
+                    if (type.objectFlags & 32 /* Mapped */) {
+                        return getAnonymousTypeInstantiation(type, mapper);
+                    }
+                    if (type.objectFlags & 4 /* Reference */) {
+                        return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper));
+                    }
+                }
+                if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) {
+                    return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
+                }
+                if (type.flags & 131072 /* Intersection */) {
+                    return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
+                }
+                if (type.flags & 262144 /* Index */) {
+                    return getIndexType(instantiateType(type.type, mapper));
+                }
+                if (type.flags & 524288 /* IndexedAccess */) {
+                    return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper));
+                }
+            }
+            return type;
+        }
+        function instantiateIndexInfo(info, mapper) {
+            return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration);
+        }
+        // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
+        // that is subject to contextual typing.
+        function isContextSensitive(node) {
+            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
+            switch (node.kind) {
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                case 151 /* MethodDeclaration */:
+                    return isContextSensitiveFunctionLikeDeclaration(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return ts.forEach(node.properties, isContextSensitive);
+                case 177 /* ArrayLiteralExpression */:
+                    return ts.forEach(node.elements, isContextSensitive);
+                case 195 /* ConditionalExpression */:
+                    return isContextSensitive(node.whenTrue) ||
+                        isContextSensitive(node.whenFalse);
+                case 194 /* BinaryExpression */:
+                    return node.operatorToken.kind === 54 /* BarBarToken */ &&
+                        (isContextSensitive(node.left) || isContextSensitive(node.right));
+                case 261 /* PropertyAssignment */:
+                    return isContextSensitive(node.initializer);
+                case 185 /* ParenthesizedExpression */:
+                    return isContextSensitive(node.expression);
+                case 254 /* JsxAttributes */:
+                    return ts.forEach(node.properties, isContextSensitive);
+                case 253 /* JsxAttribute */:
+                    // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
+                    return node.initializer && isContextSensitive(node.initializer);
+                case 256 /* JsxExpression */:
+                    // It is possible to that node.expression is undefined (e.g <div x={} />)
+                    return node.expression && isContextSensitive(node.expression);
+            }
+            return false;
+        }
+        function isContextSensitiveFunctionLikeDeclaration(node) {
+            // Functions with type parameters are not context sensitive.
+            if (node.typeParameters) {
+                return false;
+            }
+            // Functions with any parameters that lack type annotations are context sensitive.
+            if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) {
+                return true;
+            }
+            if (node.kind !== 187 /* ArrowFunction */) {
+                // If the first parameter is not an explicit 'this' parameter, then the function has
+                // an implicit 'this' parameter which is subject to contextual typing.
+                var parameter = ts.firstOrUndefined(node.parameters);
+                if (!(parameter && ts.parameterIsThisKeyword(parameter))) {
+                    return true;
+                }
+            }
+            // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
+            return node.body.kind === 207 /* Block */ ? false : isContextSensitive(node.body);
+        }
+        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
+            return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
+        }
+        function getTypeWithoutSignatures(type) {
+            if (type.flags & 32768 /* Object */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                if (resolved.constructSignatures.length) {
+                    var result = createObjectType(16 /* Anonymous */, type.symbol);
+                    result.members = resolved.members;
+                    result.properties = resolved.properties;
+                    result.callSignatures = ts.emptyArray;
+                    result.constructSignatures = ts.emptyArray;
+                    return result;
+                }
+            }
+            else if (type.flags & 131072 /* Intersection */) {
+                return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures));
+            }
+            return type;
+        }
+        // TYPE CHECKING
+        function isTypeIdenticalTo(source, target) {
+            return isTypeRelatedTo(source, target, identityRelation);
+        }
+        function compareTypesIdentical(source, target) {
+            return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */;
+        }
+        function compareTypesAssignable(source, target) {
+            return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */;
+        }
+        function isTypeSubtypeOf(source, target) {
+            return isTypeRelatedTo(source, target, subtypeRelation);
+        }
+        function isTypeAssignableTo(source, target) {
+            return isTypeRelatedTo(source, target, assignableRelation);
+        }
+        // A type S is considered to be an instance of a type T if S and T are the same type or if S is a
+        // subtype of T but not structurally identical to T. This specifically means that two distinct but
+        // structurally identical types (such as two classes) are not considered instances of each other.
+        function isTypeInstanceOf(source, target) {
+            return getTargetType(source) === getTargetType(target) || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target);
+        }
+        /**
+         * This is *not* a bi-directional relationship.
+         * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
+         *
+         * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
+         * It is used to check following cases:
+         *   - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
+         *   - the types of `case` clause expressions and their respective `switch` expressions.
+         *   - the type of an expression in a type assertion with the type being asserted.
+         */
+        function isTypeComparableTo(source, target) {
+            return isTypeRelatedTo(source, target, comparableRelation);
+        }
+        function areTypesComparable(type1, type2) {
+            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
+        }
+        function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain) {
+            return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain);
+        }
+        /**
+         * This is *not* a bi-directional relationship.
+         * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'.
+         */
+        function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) {
+            return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain);
+        }
+        function isSignatureAssignableTo(source, target, ignoreReturnTypes) {
+            return compareSignaturesRelated(source, target, 0 /* None */, ignoreReturnTypes, /*reportErrors*/ false, 
+            /*errorReporter*/ undefined, compareTypesAssignable) !== 0 /* False */;
+        }
+        /**
+         * See signatureRelatedTo, compareSignaturesIdentical
+         */
+        function compareSignaturesRelated(source, target, callbackCheck, ignoreReturnTypes, reportErrors, errorReporter, compareTypes) {
+            // TODO (drosen): De-duplicate code between related functions.
+            if (source === target) {
+                return -1 /* True */;
+            }
+            if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) {
+                return 0 /* False */;
+            }
+            if (source.typeParameters && source.typeParameters !== target.typeParameters) {
+                target = getCanonicalSignature(target);
+                source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
+            }
+            var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
+            var strictVariance = !callbackCheck && strictFunctionTypes && kind !== 151 /* MethodDeclaration */ &&
+                kind !== 150 /* MethodSignature */ && kind !== 152 /* Constructor */;
+            var result = -1 /* True */;
+            var sourceThisType = getThisTypeOfSignature(source);
+            if (sourceThisType && sourceThisType !== voidType) {
+                var targetThisType = getThisTypeOfSignature(target);
+                if (targetThisType) {
+                    // void sources are assignable to anything.
+                    var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
+                        || compareTypes(targetThisType, sourceThisType, reportErrors);
+                    if (!related) {
+                        if (reportErrors) {
+                            errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible);
+                        }
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+            }
+            var sourceMax = getNumNonRestParameters(source);
+            var targetMax = getNumNonRestParameters(target);
+            var checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax);
+            var sourceParams = source.parameters;
+            var targetParams = target.parameters;
+            for (var i = 0; i < checkCount; i++) {
+                var sourceType = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source);
+                var targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
+                // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
+                // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
+                // they naturally relate only contra-variantly). However, if the source and target parameters both have
+                // function types with a single call signature, we know we are relating two callback parameters. In
+                // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
+                // similar to return values, callback parameters are output positions. This means that a Promise<T>,
+                // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
+                // with respect to T.
+                var sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
+                var targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
+                var callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate &&
+                    (getFalsyFlags(sourceType) & 6144 /* Nullable */) === (getFalsyFlags(targetType) & 6144 /* Nullable */);
+                var related = callbacks ?
+                    compareSignaturesRelated(targetSig, sourceSig, strictVariance ? 2 /* Strict */ : 1 /* Bivariant */, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
+                    !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
+                if (!related) {
+                    if (reportErrors) {
+                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.symbolName(sourceParams[i < sourceMax ? i : sourceMax]), ts.symbolName(targetParams[i < targetMax ? i : targetMax]));
+                    }
+                    return 0 /* False */;
+                }
+                result &= related;
+            }
+            if (!ignoreReturnTypes) {
+                var targetReturnType = getReturnTypeOfSignature(target);
+                if (targetReturnType === voidType) {
+                    return result;
+                }
+                var sourceReturnType = getReturnTypeOfSignature(source);
+                // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
+                if (target.typePredicate) {
+                    if (source.typePredicate) {
+                        result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
+                    }
+                    else if (ts.isIdentifierTypePredicate(target.typePredicate)) {
+                        if (reportErrors) {
+                            errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
+                        }
+                        return 0 /* False */;
+                    }
+                }
+                else {
+                    // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
+                    // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
+                    // wouldn't be co-variant for T without this rule.
+                    result &= callbackCheck === 1 /* Bivariant */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
+                        compareTypes(sourceReturnType, targetReturnType, reportErrors);
+                }
+            }
+            return result;
+        }
+        function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) {
+            if (source.kind !== target.kind) {
+                if (reportErrors) {
+                    errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
+                    errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
+                }
+                return 0 /* False */;
+            }
+            if (source.kind === 1 /* Identifier */) {
+                var sourcePredicate = source;
+                var targetPredicate = target;
+                var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0);
+                var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0);
+                if (sourceIndex !== targetIndex) {
+                    if (reportErrors) {
+                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName);
+                        errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
+                    }
+                    return 0 /* False */;
+                }
+            }
+            var related = compareTypes(source.type, target.type, reportErrors);
+            if (related === 0 /* False */ && reportErrors) {
+                errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
+            }
+            return related;
+        }
+        function isImplementationCompatibleWithOverload(implementation, overload) {
+            var erasedSource = getErasedSignature(implementation);
+            var erasedTarget = getErasedSignature(overload);
+            // First see if the return types are compatible in either direction.
+            var sourceReturnType = getReturnTypeOfSignature(erasedSource);
+            var targetReturnType = getReturnTypeOfSignature(erasedTarget);
+            if (targetReturnType === voidType
+                || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation)
+                || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) {
+                return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
+            }
+            return false;
+        }
+        function getNumNonRestParameters(signature) {
+            var numParams = signature.parameters.length;
+            return signature.hasRestParameter ?
+                numParams - 1 :
+                numParams;
+        }
+        function getNumParametersToCheckForSignatureRelatability(source, sourceNonRestParamCount, target, targetNonRestParamCount) {
+            if (source.hasRestParameter === target.hasRestParameter) {
+                if (source.hasRestParameter) {
+                    // If both have rest parameters, get the max and add 1 to
+                    // compensate for the rest parameter.
+                    return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1;
+                }
+                else {
+                    return Math.min(sourceNonRestParamCount, targetNonRestParamCount);
+                }
+            }
+            else {
+                // Return the count for whichever signature doesn't have rest parameters.
+                return source.hasRestParameter ?
+                    targetNonRestParamCount :
+                    sourceNonRestParamCount;
+            }
+        }
+        function isEmptyResolvedType(t) {
+            return t.properties.length === 0 &&
+                t.callSignatures.length === 0 &&
+                t.constructSignatures.length === 0 &&
+                !t.stringIndexInfo &&
+                !t.numberIndexInfo;
+        }
+        function isEmptyObjectType(type) {
+            return type.flags & 32768 /* Object */ ? isEmptyResolvedType(resolveStructuredTypeMembers(type)) :
+                type.flags & 16777216 /* NonPrimitive */ ? true :
+                    type.flags & 65536 /* Union */ ? ts.forEach(type.types, isEmptyObjectType) :
+                        type.flags & 131072 /* Intersection */ ? !ts.forEach(type.types, function (t) { return !isEmptyObjectType(t); }) :
+                            false;
+        }
+        function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) {
+            if (sourceSymbol === targetSymbol) {
+                return true;
+            }
+            var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
+            var relation = enumRelation.get(id);
+            if (relation !== undefined) {
+                return relation;
+            }
+            if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) {
+                enumRelation.set(id, false);
+                return false;
+            }
+            var targetEnumType = getTypeOfSymbol(targetSymbol);
+            for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) {
+                var property = _a[_i];
+                if (property.flags & 8 /* EnumMember */) {
+                    var targetProperty = getPropertyOfType(targetEnumType, property.escapedName);
+                    if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
+                        if (errorReporter) {
+                            errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */));
+                        }
+                        enumRelation.set(id, false);
+                        return false;
+                    }
+                }
+            }
+            enumRelation.set(id, true);
+            return true;
+        }
+        function isSimpleTypeRelatedTo(source, target, relation, errorReporter) {
+            var s = source.flags;
+            var t = target.flags;
+            if (t & 8192 /* Never */)
+                return false;
+            if (t & 1 /* Any */ || s & 8192 /* Never */)
+                return true;
+            if (s & 262178 /* StringLike */ && t & 2 /* String */)
+                return true;
+            if (s & 32 /* StringLiteral */ && s & 256 /* EnumLiteral */ &&
+                t & 32 /* StringLiteral */ && !(t & 256 /* EnumLiteral */) &&
+                source.value === target.value)
+                return true;
+            if (s & 84 /* NumberLike */ && t & 4 /* Number */)
+                return true;
+            if (s & 64 /* NumberLiteral */ && s & 256 /* EnumLiteral */ &&
+                t & 64 /* NumberLiteral */ && !(t & 256 /* EnumLiteral */) &&
+                source.value === target.value)
+                return true;
+            if (s & 136 /* BooleanLike */ && t & 8 /* Boolean */)
+                return true;
+            if (s & 16 /* Enum */ && t & 16 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
+                return true;
+            if (s & 256 /* EnumLiteral */ && t & 256 /* EnumLiteral */) {
+                if (s & 65536 /* Union */ && t & 65536 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
+                    return true;
+                if (s & 224 /* Literal */ && t & 224 /* Literal */ &&
+                    source.value === target.value &&
+                    isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter))
+                    return true;
+            }
+            if (s & 2048 /* Undefined */ && (!strictNullChecks || t & (2048 /* Undefined */ | 1024 /* Void */)))
+                return true;
+            if (s & 4096 /* Null */ && (!strictNullChecks || t & 4096 /* Null */))
+                return true;
+            if (s & 32768 /* Object */ && t & 16777216 /* NonPrimitive */)
+                return true;
+            if (relation === assignableRelation || relation === comparableRelation) {
+                if (s & 1 /* Any */)
+                    return true;
+                // Type number or any numeric literal type is assignable to any numeric enum type or any
+                // numeric enum literal type. This rule exists for backwards compatibility reasons because
+                // bit-flag enum types sometimes look like literal enum types with numeric literal values.
+                if (s & (4 /* Number */ | 64 /* NumberLiteral */) && !(s & 256 /* EnumLiteral */) && (t & 16 /* Enum */ || t & 64 /* NumberLiteral */ && t & 256 /* EnumLiteral */))
+                    return true;
+            }
+            return false;
+        }
+        function isTypeRelatedTo(source, target, relation) {
+            if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
+                source = source.regularType;
+            }
+            if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 1048576 /* FreshLiteral */) {
+                target = target.regularType;
+            }
+            if (source === target || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
+                return true;
+            }
+            if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) {
+                var related = relation.get(getRelationKey(source, target, relation));
+                if (related !== undefined) {
+                    return related === 1 /* Succeeded */;
+                }
+            }
+            if (source.flags & 1032192 /* StructuredOrTypeVariable */ || target.flags & 1032192 /* StructuredOrTypeVariable */) {
+                return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
+            }
+            return false;
+        }
+        /**
+         * Checks if 'source' is related to 'target' (e.g.: is a assignable to).
+         * @param source The left-hand-side of the relation.
+         * @param target The right-hand-side of the relation.
+         * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'.
+         * Used as both to determine which checks are performed and as a cache of previously computed results.
+         * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
+         * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
+         * @param containingMessageChain A chain of errors to prepend any new errors found.
+         */
+        function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain) {
+            var errorInfo;
+            var maybeKeys;
+            var sourceStack;
+            var targetStack;
+            var maybeCount = 0;
+            var depth = 0;
+            var ExpandingFlags;
+            (function (ExpandingFlags) {
+                ExpandingFlags[ExpandingFlags["None"] = 0] = "None";
+                ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source";
+                ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target";
+                ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both";
+            })(ExpandingFlags || (ExpandingFlags = {}));
+            var expandingFlags = 0 /* None */;
+            var overflow = false;
+            var isIntersectionConstituent = false;
+            ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
+            var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
+            if (overflow) {
+                error(errorNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
+            }
+            else if (errorInfo) {
+                if (containingMessageChain) {
+                    errorInfo = ts.concatenateDiagnosticMessageChains(containingMessageChain, errorInfo);
+                }
+                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo));
+            }
+            return result !== 0 /* False */;
+            function reportError(message, arg0, arg1, arg2) {
+                ts.Debug.assert(!!errorNode);
+                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
+            }
+            function reportRelationError(message, source, target) {
+                var sourceType = typeToString(source);
+                var targetType = typeToString(target);
+                if (sourceType === targetType) {
+                    sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */);
+                    targetType = typeToString(target, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */);
+                }
+                if (!message) {
+                    if (relation === comparableRelation) {
+                        message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1;
+                    }
+                    else if (sourceType === targetType) {
+                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
+                    }
+                    else {
+                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
+                    }
+                }
+                reportError(message, sourceType, targetType);
+            }
+            function tryElaborateErrorsForPrimitivesAndObjects(source, target) {
+                var sourceType = typeToString(source);
+                var targetType = typeToString(target);
+                if ((globalStringType === source && stringType === target) ||
+                    (globalNumberType === source && numberType === target) ||
+                    (globalBooleanType === source && booleanType === target) ||
+                    (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) {
+                    reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
+                }
+            }
+            function isUnionOrIntersectionTypeWithoutNullableConstituents(type) {
+                if (!(type.flags & 196608 /* UnionOrIntersection */)) {
+                    return false;
+                }
+                // at this point we know that this is union or intersection type possibly with nullable constituents.
+                // check if we still will have compound type if we ignore nullable components.
+                var seenNonNullable = false;
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    if (t.flags & 6144 /* Nullable */) {
+                        continue;
+                    }
+                    if (seenNonNullable) {
+                        return true;
+                    }
+                    seenNonNullable = true;
+                }
+                return false;
+            }
+            /**
+             * Compare two types and return
+             * * Ternary.True if they are related with no assumptions,
+             * * Ternary.Maybe if they are related with assumptions of other relationships, or
+             * * Ternary.False if they are not related.
+             */
+            function isRelatedTo(source, target, reportErrors, headMessage) {
+                if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
+                    source = source.regularType;
+                }
+                if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 1048576 /* FreshLiteral */) {
+                    target = target.regularType;
+                }
+                // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
+                if (source === target)
+                    return -1 /* True */;
+                if (relation === identityRelation) {
+                    return isIdenticalTo(source, target);
+                }
+                if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined))
+                    return -1 /* True */;
+                if (getObjectFlags(source) & 128 /* ObjectLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
+                    if (hasExcessProperties(source, target, reportErrors)) {
+                        if (reportErrors) {
+                            reportRelationError(headMessage, source, target);
+                        }
+                        return 0 /* False */;
+                    }
+                    // Above we check for excess properties with respect to the entire target type. When union
+                    // and intersection types are further deconstructed on the target side, we don't want to
+                    // make the check again (as it might fail for a partial target type). Therefore we obtain
+                    // the regular source type and proceed with that.
+                    if (isUnionOrIntersectionTypeWithoutNullableConstituents(target)) {
+                        source = getRegularTypeOfObjectLiteral(source);
+                    }
+                }
+                if (relation !== comparableRelation &&
+                    !(source.flags & 196608 /* UnionOrIntersection */) &&
+                    !(target.flags & 65536 /* Union */) &&
+                    !isIntersectionConstituent &&
+                    source !== globalObjectType &&
+                    (getPropertiesOfType(source).length > 0 ||
+                        getSignaturesOfType(source, 0 /* Call */).length > 0 ||
+                        getSignaturesOfType(source, 1 /* Construct */).length > 0) &&
+                    isWeakType(target) &&
+                    !hasCommonProperties(source, target)) {
+                    if (reportErrors) {
+                        var calls = getSignaturesOfType(source, 0 /* Call */);
+                        var constructs = getSignaturesOfType(source, 1 /* Construct */);
+                        if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) ||
+                            constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) {
+                            reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target));
+                        }
+                        else {
+                            reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
+                        }
+                    }
+                    return 0 /* False */;
+                }
+                var result = 0 /* False */;
+                var saveErrorInfo = errorInfo;
+                var saveIsIntersectionConstituent = isIntersectionConstituent;
+                isIntersectionConstituent = false;
+                // Note that these checks are specifically ordered to produce correct results. In particular,
+                // we need to deconstruct unions before intersections (because unions are always at the top),
+                // and we need to handle "each" relations before "some" relations for the same kind of type.
+                if (source.flags & 65536 /* Union */) {
+                    result = relation === comparableRelation ?
+                        someTypeRelatedToType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */)) :
+                        eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */));
+                }
+                else {
+                    if (target.flags & 65536 /* Union */) {
+                        result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */) && !(target.flags & 8190 /* Primitive */));
+                    }
+                    else if (target.flags & 131072 /* Intersection */) {
+                        isIntersectionConstituent = true;
+                        result = typeRelatedToEachType(source, target, reportErrors);
+                    }
+                    else if (source.flags & 131072 /* Intersection */) {
+                        // Check to see if any constituents of the intersection are immediately related to the target.
+                        //
+                        // Don't report errors though. Checking whether a constituent is related to the source is not actually
+                        // useful and leads to some confusing error messages. Instead it is better to let the below checks
+                        // take care of this, or to not elaborate at all. For instance,
+                        //
+                        //    - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
+                        //
+                        //    - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
+                        //          than to report that 'D' is not assignable to 'A' or 'B'.
+                        //
+                        //    - For a primitive type or type parameter (such as 'number = A & B') there is no point in
+                        //          breaking the intersection apart.
+                        result = someTypeRelatedToType(source, target, /*reportErrors*/ false);
+                    }
+                    if (!result && (source.flags & 1032192 /* StructuredOrTypeVariable */ || target.flags & 1032192 /* StructuredOrTypeVariable */)) {
+                        if (result = recursiveTypeRelatedTo(source, target, reportErrors)) {
+                            errorInfo = saveErrorInfo;
+                        }
+                    }
+                }
+                isIntersectionConstituent = saveIsIntersectionConstituent;
+                if (!result && reportErrors) {
+                    if (source.flags & 32768 /* Object */ && target.flags & 8190 /* Primitive */) {
+                        tryElaborateErrorsForPrimitivesAndObjects(source, target);
+                    }
+                    else if (source.symbol && source.flags & 32768 /* Object */ && globalObjectType === source) {
+                        reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
+                    }
+                    reportRelationError(headMessage, source, target);
+                }
+                return result;
+            }
+            function isIdenticalTo(source, target) {
+                var result;
+                if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) {
+                    return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false);
+                }
+                if (source.flags & 65536 /* Union */ && target.flags & 65536 /* Union */ ||
+                    source.flags & 131072 /* Intersection */ && target.flags & 131072 /* Intersection */) {
+                    if (result = eachTypeRelatedToSomeType(source, target)) {
+                        if (result &= eachTypeRelatedToSomeType(target, source)) {
+                            return result;
+                        }
+                    }
+                }
+                return 0 /* False */;
+            }
+            function hasExcessProperties(source, target, reportErrors) {
+                if (maybeTypeOfKind(target, 32768 /* Object */) && !(getObjectFlags(target) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
+                    var isComparingJsxAttributes = !!(source.flags & 33554432 /* JsxAttributes */);
+                    if ((relation === assignableRelation || relation === comparableRelation) &&
+                        (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
+                        return false;
+                    }
+                    if (target.flags & 65536 /* Union */) {
+                        var discriminantType = findMatchingDiscriminantType(source, target);
+                        if (discriminantType) {
+                            // check excess properties against discriminant type only, not the entire union
+                            return hasExcessProperties(source, discriminantType, reportErrors);
+                        }
+                    }
+                    var _loop_4 = function (prop) {
+                        if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
+                            if (reportErrors) {
+                                // We know *exactly* where things went wrong when comparing the types.
+                                // Use this property as the error node as this will be more helpful in
+                                // reasoning about what went wrong.
+                                ts.Debug.assert(!!errorNode);
+                                if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode)) {
+                                    // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
+                                    // However, using an object-literal error message will be very confusing to the users so we give different a message.
+                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
+                                }
+                                else {
+                                    // use the property's value declaration if the property is assigned inside the literal itself
+                                    var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations);
+                                    var suggestion = void 0;
+                                    if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; })) {
+                                        var propDeclaration = prop.valueDeclaration;
+                                        ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike);
+                                        errorNode = propDeclaration;
+                                        if (ts.isIdentifier(propDeclaration.name)) {
+                                            suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, target);
+                                        }
+                                    }
+                                    if (suggestion !== undefined) {
+                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(target), suggestion);
+                                    }
+                                    else {
+                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target));
+                                    }
+                                }
+                            }
+                            return { value: true };
+                        }
+                    };
+                    for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
+                        var prop = _a[_i];
+                        var state_2 = _loop_4(prop);
+                        if (typeof state_2 === "object")
+                            return state_2.value;
+                    }
+                }
+                return false;
+            }
+            function eachTypeRelatedToSomeType(source, target) {
+                var result = -1 /* True */;
+                var sourceTypes = source.types;
+                for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) {
+                    var sourceType = sourceTypes_1[_i];
+                    var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
+                    if (!related) {
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+                return result;
+            }
+            function typeRelatedToSomeType(source, target, reportErrors) {
+                var targetTypes = target.types;
+                if (target.flags & 65536 /* Union */ && containsType(targetTypes, source)) {
+                    return -1 /* True */;
+                }
+                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
+                    var type = targetTypes_1[_i];
+                    var related = isRelatedTo(source, type, /*reportErrors*/ false);
+                    if (related) {
+                        return related;
+                    }
+                }
+                if (reportErrors) {
+                    var discriminantType = findMatchingDiscriminantType(source, target);
+                    isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
+                }
+                return 0 /* False */;
+            }
+            function findMatchingDiscriminantType(source, target) {
+                var match;
+                var sourceProperties = getPropertiesOfObjectType(source);
+                if (sourceProperties) {
+                    var sourceProperty = findSingleDiscriminantProperty(sourceProperties, target);
+                    if (sourceProperty) {
+                        var sourceType = getTypeOfSymbol(sourceProperty);
+                        for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
+                            var type = _a[_i];
+                            var targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName);
+                            if (targetType && isRelatedTo(sourceType, targetType)) {
+                                if (match) {
+                                    return undefined;
+                                }
+                                match = type;
+                            }
+                        }
+                    }
+                }
+                return match;
+            }
+            function typeRelatedToEachType(source, target, reportErrors) {
+                var result = -1 /* True */;
+                var targetTypes = target.types;
+                for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) {
+                    var targetType = targetTypes_2[_i];
+                    var related = isRelatedTo(source, targetType, reportErrors);
+                    if (!related) {
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+                return result;
+            }
+            function someTypeRelatedToType(source, target, reportErrors) {
+                var sourceTypes = source.types;
+                if (source.flags & 65536 /* Union */ && containsType(sourceTypes, target)) {
+                    return -1 /* True */;
+                }
+                var len = sourceTypes.length;
+                for (var i = 0; i < len; i++) {
+                    var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1);
+                    if (related) {
+                        return related;
+                    }
+                }
+                return 0 /* False */;
+            }
+            function eachTypeRelatedToType(source, target, reportErrors) {
+                var result = -1 /* True */;
+                var sourceTypes = source.types;
+                for (var _i = 0, sourceTypes_2 = sourceTypes; _i < sourceTypes_2.length; _i++) {
+                    var sourceType = sourceTypes_2[_i];
+                    var related = isRelatedTo(sourceType, target, reportErrors);
+                    if (!related) {
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+                return result;
+            }
+            function typeArgumentsRelatedTo(source, target, variances, reportErrors) {
+                var sources = source.typeArguments || ts.emptyArray;
+                var targets = target.typeArguments || ts.emptyArray;
+                if (sources.length !== targets.length && relation === identityRelation) {
+                    return 0 /* False */;
+                }
+                var length = sources.length <= targets.length ? sources.length : targets.length;
+                var result = -1 /* True */;
+                for (var i = 0; i < length; i++) {
+                    // When variance information isn't available we default to covariance. This happens
+                    // in the process of computing variance information for recursive types and when
+                    // comparing 'this' type arguments.
+                    var variance = i < variances.length ? variances[i] : 1 /* Covariant */;
+                    // We ignore arguments for independent type parameters (because they're never witnessed).
+                    if (variance !== 4 /* Independent */) {
+                        var s = sources[i];
+                        var t = targets[i];
+                        var related = -1 /* True */;
+                        if (variance === 1 /* Covariant */) {
+                            related = isRelatedTo(s, t, reportErrors);
+                        }
+                        else if (variance === 2 /* Contravariant */) {
+                            related = isRelatedTo(t, s, reportErrors);
+                        }
+                        else if (variance === 3 /* Bivariant */) {
+                            // In the bivariant case we first compare contravariantly without reporting
+                            // errors. Then, if that doesn't succeed, we compare covariantly with error
+                            // reporting. Thus, error elaboration will be based on the the covariant check,
+                            // which is generally easier to reason about.
+                            related = isRelatedTo(t, s, /*reportErrors*/ false);
+                            if (!related) {
+                                related = isRelatedTo(s, t, reportErrors);
+                            }
+                        }
+                        else {
+                            // In the invariant case we first compare covariantly, and only when that
+                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
+                            // will typically be based on the covariant check.
+                            related = isRelatedTo(s, t, reportErrors);
+                            if (related) {
+                                related &= isRelatedTo(t, s, reportErrors);
+                            }
+                        }
+                        if (!related) {
+                            return 0 /* False */;
+                        }
+                        result &= related;
+                    }
+                }
+                return result;
+            }
+            // Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
+            // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
+            // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
+            // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
+            // and issue an error. Otherwise, actually compare the structure of the two types.
+            function recursiveTypeRelatedTo(source, target, reportErrors) {
+                if (overflow) {
+                    return 0 /* False */;
+                }
+                var id = getRelationKey(source, target, relation);
+                var related = relation.get(id);
+                if (related !== undefined) {
+                    if (reportErrors && related === 2 /* Failed */) {
+                        // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
+                        // failure and continue computing the relation such that errors get reported.
+                        relation.set(id, 3 /* FailedAndReported */);
+                    }
+                    else {
+                        return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
+                    }
+                }
+                if (!maybeKeys) {
+                    maybeKeys = [];
+                    sourceStack = [];
+                    targetStack = [];
+                }
+                else {
+                    for (var i = 0; i < maybeCount; i++) {
+                        // If source and target are already being compared, consider them related with assumptions
+                        if (id === maybeKeys[i]) {
+                            return 1 /* Maybe */;
+                        }
+                    }
+                    if (depth === 100) {
+                        overflow = true;
+                        return 0 /* False */;
+                    }
+                }
+                var maybeStart = maybeCount;
+                maybeKeys[maybeCount] = id;
+                maybeCount++;
+                sourceStack[depth] = source;
+                targetStack[depth] = target;
+                depth++;
+                var saveExpandingFlags = expandingFlags;
+                if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth))
+                    expandingFlags |= 1 /* Source */;
+                if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth))
+                    expandingFlags |= 2 /* Target */;
+                var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors) : 1 /* Maybe */;
+                expandingFlags = saveExpandingFlags;
+                depth--;
+                if (result) {
+                    if (result === -1 /* True */ || depth === 0) {
+                        // If result is definitely true, record all maybe keys as having succeeded
+                        for (var i = maybeStart; i < maybeCount; i++) {
+                            relation.set(maybeKeys[i], 1 /* Succeeded */);
+                        }
+                        maybeCount = maybeStart;
+                    }
+                }
+                else {
+                    // A false result goes straight into global cache (when something is false under
+                    // assumptions it will also be false without assumptions)
+                    relation.set(id, reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */);
+                    maybeCount = maybeStart;
+                }
+                return result;
+            }
+            function structuredTypeRelatedTo(source, target, reportErrors) {
+                var result;
+                var saveErrorInfo = errorInfo;
+                if (target.flags & 16384 /* TypeParameter */) {
+                    // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P].
+                    if (getObjectFlags(source) & 32 /* Mapped */ && getConstraintTypeFromMappedType(source) === getIndexType(target)) {
+                        if (!source.declaration.questionToken) {
+                            var templateType = getTemplateTypeFromMappedType(source);
+                            var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source));
+                            if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) {
+                                return result;
+                            }
+                        }
+                    }
+                }
+                else if (target.flags & 262144 /* Index */) {
+                    // A keyof S is related to a keyof T if T is related to S.
+                    if (source.flags & 262144 /* Index */) {
+                        if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) {
+                            return result;
+                        }
+                    }
+                    // A type S is assignable to keyof T if S is assignable to keyof C, where C is the
+                    // constraint of T.
+                    var constraint = getConstraintOfType(target.type);
+                    if (constraint) {
+                        if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
+                            return result;
+                        }
+                    }
+                }
+                else if (target.flags & 524288 /* IndexedAccess */) {
+                    // A type S is related to a type T[K] if S is related to A[K], where K is string-like and
+                    // A is the apparent type of S.
+                    var constraint = getConstraintOfIndexedAccess(target);
+                    if (constraint) {
+                        if (result = isRelatedTo(source, constraint, reportErrors)) {
+                            errorInfo = saveErrorInfo;
+                            return result;
+                        }
+                    }
+                }
+                if (source.flags & 16384 /* TypeParameter */) {
+                    // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
+                    if (getObjectFlags(target) & 32 /* Mapped */ && getConstraintTypeFromMappedType(target) === getIndexType(source)) {
+                        var indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target));
+                        var templateType = getTemplateTypeFromMappedType(target);
+                        if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
+                            errorInfo = saveErrorInfo;
+                            return result;
+                        }
+                    }
+                    else {
+                        var constraint = getConstraintOfTypeParameter(source);
+                        // A type parameter with no constraint is not related to the non-primitive object type.
+                        if (constraint || !(target.flags & 16777216 /* NonPrimitive */)) {
+                            if (!constraint || constraint.flags & 1 /* Any */) {
+                                constraint = emptyObjectType;
+                            }
+                            // Report constraint errors only if the constraint is not the empty object type
+                            var reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
+                            if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
+                                errorInfo = saveErrorInfo;
+                                return result;
+                            }
+                        }
+                    }
+                }
+                else if (source.flags & 524288 /* IndexedAccess */) {
+                    // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
+                    // A is the apparent type of S.
+                    var constraint = getConstraintOfIndexedAccess(source);
+                    if (constraint) {
+                        if (result = isRelatedTo(constraint, target, reportErrors)) {
+                            errorInfo = saveErrorInfo;
+                            return result;
+                        }
+                    }
+                    else if (target.flags & 524288 /* IndexedAccess */ && source.indexType === target.indexType) {
+                        // if we have indexed access types with identical index types, see if relationship holds for
+                        // the two object types.
+                        if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) {
+                            return result;
+                        }
+                    }
+                }
+                else {
+                    if (getObjectFlags(source) & 4 /* Reference */ && getObjectFlags(target) & 4 /* Reference */ && source.target === target.target &&
+                        !(source.flags & 67108864 /* MarkerType */ || target.flags & 67108864 /* MarkerType */)) {
+                        // We have type references to the same generic type, and the type references are not marker
+                        // type references (which are intended by be compared structurally). Obtain the variance
+                        // information for the type parameters and relate the type arguments accordingly.
+                        var variances = getVariances(source.target);
+                        if (result = typeArgumentsRelatedTo(source, target, variances, reportErrors)) {
+                            return result;
+                        }
+                        // The type arguments did not relate appropriately, but it may be because we have no variance
+                        // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
+                        // arguments). It might also be the case that the target type has a 'void' type argument for
+                        // a covariant type parameter that is only used in return positions within the generic type
+                        // (in which case any type argument is permitted on the source side). In those cases we proceed
+                        // with a structural comparison. Otherwise, we know for certain the instantiations aren't
+                        // related and we can return here.
+                        if (variances !== ts.emptyArray && !hasCovariantVoidArgument(target, variances)) {
+                            // In some cases generic types that are covariant in regular type checking mode become
+                            // invariant in --strictFunctionTypes mode because one or more type parameters are used in
+                            // both co- and contravariant positions. In order to make it easier to diagnose *why* such
+                            // types are invariant, if any of the type parameters are invariant we reset the reported
+                            // errors and instead force a structural comparison (which will include elaborations that
+                            // reveal the reason).
+                            if (!(reportErrors && ts.some(variances, function (v) { return v === 0 /* Invariant */; }))) {
+                                return 0 /* False */;
+                            }
+                            errorInfo = saveErrorInfo;
+                        }
+                    }
+                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
+                    // it may hold in a structural comparison.
+                    var sourceIsPrimitive = !!(source.flags & 8190 /* Primitive */);
+                    if (relation !== identityRelation) {
+                        source = getApparentType(source);
+                    }
+                    // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
+                    // to X. Failing both of those we want to check if the aggregation of A and B's members structurally
+                    // relates to X. Thus, we include intersection types on the source side here.
+                    if (source.flags & (32768 /* Object */ | 131072 /* Intersection */) && target.flags & 32768 /* Object */) {
+                        // Report structural errors only if we haven't reported any errors yet
+                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive;
+                        // An empty object type is related to any mapped type that includes a '?' modifier.
+                        if (isPartialMappedType(target) && !isGenericMappedType(source) && isEmptyObjectType(source)) {
+                            result = -1 /* True */;
+                        }
+                        else if (isGenericMappedType(target)) {
+                            result = isGenericMappedType(source) ? mappedTypeRelatedTo(source, target, reportStructuralErrors) : 0 /* False */;
+                        }
+                        else {
+                            result = propertiesRelatedTo(source, target, reportStructuralErrors);
+                            if (result) {
+                                result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors);
+                                if (result) {
+                                    result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors);
+                                    if (result) {
+                                        result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors);
+                                        if (result) {
+                                            result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        if (result) {
+                            errorInfo = saveErrorInfo;
+                            return result;
+                        }
+                    }
+                }
+                return 0 /* False */;
+            }
+            // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
+            // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
+            // that S and T are contra-variant whereas X and Y are co-variant.
+            function mappedTypeRelatedTo(source, target, reportErrors) {
+                var sourceReadonly = !!source.declaration.readonlyToken;
+                var sourceOptional = !!source.declaration.questionToken;
+                var targetReadonly = !!target.declaration.readonlyToken;
+                var targetOptional = !!target.declaration.questionToken;
+                var modifiersRelated = relation === identityRelation ?
+                    sourceReadonly === targetReadonly && sourceOptional === targetOptional :
+                    relation === comparableRelation || !sourceOptional || targetOptional;
+                if (modifiersRelated) {
+                    var result_2;
+                    if (result_2 = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) {
+                        var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
+                        return result_2 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
+                    }
+                }
+                return 0 /* False */;
+            }
+            function propertiesRelatedTo(source, target, reportErrors) {
+                if (relation === identityRelation) {
+                    return propertiesIdenticalTo(source, target);
+                }
+                var requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & 128 /* ObjectLiteral */);
+                var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
+                if (unmatchedProperty) {
+                    if (reportErrors) {
+                        reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source));
+                    }
+                    return 0 /* False */;
+                }
+                var result = -1 /* True */;
+                var properties = getPropertiesOfObjectType(target);
+                for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
+                    var targetProp = properties_3[_i];
+                    if (!(targetProp.flags & 4194304 /* Prototype */)) {
+                        var sourceProp = getPropertyOfType(source, targetProp.escapedName);
+                        if (sourceProp && sourceProp !== targetProp) {
+                            var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp);
+                            var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp);
+                            if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
+                                if (ts.getCheckFlags(sourceProp) & 256 /* ContainsPrivate */) {
+                                    if (reportErrors) {
+                                        reportError(ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
+                                    }
+                                    return 0 /* False */;
+                                }
+                                if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
+                                    if (reportErrors) {
+                                        if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) {
+                                            reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
+                                        }
+                                        else {
+                                            reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source));
+                                        }
+                                    }
+                                    return 0 /* False */;
+                                }
+                            }
+                            else if (targetPropFlags & 16 /* Protected */) {
+                                if (!isValidOverrideOf(sourceProp, targetProp)) {
+                                    if (reportErrors) {
+                                        reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
+                                    }
+                                    return 0 /* False */;
+                                }
+                            }
+                            else if (sourcePropFlags & 16 /* Protected */) {
+                                if (reportErrors) {
+                                    reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
+                                }
+                                return 0 /* False */;
+                            }
+                            var related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors);
+                            if (!related) {
+                                if (reportErrors) {
+                                    reportError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
+                                }
+                                return 0 /* False */;
+                            }
+                            result &= related;
+                            // When checking for comparability, be more lenient with optional properties.
+                            if (relation !== comparableRelation && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) {
+                                // TypeScript 1.0 spec (April 2014): 3.8.3
+                                // S is a subtype of a type T, and T is a supertype of S if ...
+                                // S' and T are object types and, for each member M in T..
+                                // M is a property and S' contains a property N where
+                                // if M is a required property, N is also a required property
+                                // (M - property in T)
+                                // (N - property in S)
+                                if (reportErrors) {
+                                    reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
+                                }
+                                return 0 /* False */;
+                            }
+                        }
+                    }
+                }
+                return result;
+            }
+            /**
+             * A type is 'weak' if it is an object type with at least one optional property
+             * and no required properties, call/construct signatures or index signatures
+             */
+            function isWeakType(type) {
+                if (type.flags & 32768 /* Object */) {
+                    var resolved = resolveStructuredTypeMembers(type);
+                    return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
+                        !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
+                        resolved.properties.length > 0 &&
+                        ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); });
+                }
+                if (type.flags & 131072 /* Intersection */) {
+                    return ts.every(type.types, isWeakType);
+                }
+                return false;
+            }
+            function hasCommonProperties(source, target) {
+                var isComparingJsxAttributes = !!(source.flags & 33554432 /* JsxAttributes */);
+                for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+            function propertiesIdenticalTo(source, target) {
+                if (!(source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */)) {
+                    return 0 /* False */;
+                }
+                var sourceProperties = getPropertiesOfObjectType(source);
+                var targetProperties = getPropertiesOfObjectType(target);
+                if (sourceProperties.length !== targetProperties.length) {
+                    return 0 /* False */;
+                }
+                var result = -1 /* True */;
+                for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) {
+                    var sourceProp = sourceProperties_1[_i];
+                    var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName);
+                    if (!targetProp) {
+                        return 0 /* False */;
+                    }
+                    var related = compareProperties(sourceProp, targetProp, isRelatedTo);
+                    if (!related) {
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+                return result;
+            }
+            function signaturesRelatedTo(source, target, kind, reportErrors) {
+                if (relation === identityRelation) {
+                    return signaturesIdenticalTo(source, target, kind);
+                }
+                if (target === anyFunctionType || source === anyFunctionType) {
+                    return -1 /* True */;
+                }
+                var sourceSignatures = getSignaturesOfType(source, kind);
+                var targetSignatures = getSignaturesOfType(target, kind);
+                if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) {
+                    if (isAbstractConstructorType(source) && !isAbstractConstructorType(target)) {
+                        // An abstract constructor type is not assignable to a non-abstract constructor type
+                        // as it would otherwise be possible to new an abstract class. Note that the assignability
+                        // check we perform for an extends clause excludes construct signatures from the target,
+                        // so this check never proceeds.
+                        if (reportErrors) {
+                            reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
+                        }
+                        return 0 /* False */;
+                    }
+                    if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) {
+                        return 0 /* False */;
+                    }
+                }
+                var result = -1 /* True */;
+                var saveErrorInfo = errorInfo;
+                if (getObjectFlags(source) & 64 /* Instantiated */ && getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) {
+                    // We have instantiations of the same anonymous type (which typically will be the type of a
+                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
+                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
+                    // as they are known to always be the same.
+                    for (var i = 0; i < targetSignatures.length; i++) {
+                        var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors);
+                        if (!related) {
+                            return 0 /* False */;
+                        }
+                        result &= related;
+                    }
+                }
+                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
+                    // For simple functions (functions with a single signature) we only erase type parameters for
+                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
+                    // in the context of the target signature before checking the relationship. Ideally we'd do
+                    // this regardless of the number of signatures, but the potential costs are prohibitive due
+                    // to the quadratic nature of the logic below.
+                    var eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks;
+                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
+                }
+                else {
+                    outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) {
+                        var t = targetSignatures_1[_i];
+                        // Only elaborate errors from the first failure
+                        var shouldElaborateErrors = reportErrors;
+                        for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) {
+                            var s = sourceSignatures_1[_a];
+                            var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors);
+                            if (related) {
+                                result &= related;
+                                errorInfo = saveErrorInfo;
+                                continue outer;
+                            }
+                            shouldElaborateErrors = false;
+                        }
+                        if (shouldElaborateErrors) {
+                            reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind));
+                        }
+                        return 0 /* False */;
+                    }
+                }
+                return result;
+            }
+            /**
+             * See signatureAssignableTo, compareSignaturesIdentical
+             */
+            function signatureRelatedTo(source, target, erase, reportErrors) {
+                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, 0 /* None */, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
+            }
+            function signaturesIdenticalTo(source, target, kind) {
+                var sourceSignatures = getSignaturesOfType(source, kind);
+                var targetSignatures = getSignaturesOfType(target, kind);
+                if (sourceSignatures.length !== targetSignatures.length) {
+                    return 0 /* False */;
+                }
+                var result = -1 /* True */;
+                for (var i = 0; i < sourceSignatures.length; i++) {
+                    var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
+                    if (!related) {
+                        return 0 /* False */;
+                    }
+                    result &= related;
+                }
+                return result;
+            }
+            function eachPropertyRelatedTo(source, target, kind, reportErrors) {
+                var result = -1 /* True */;
+                for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
+                        var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors);
+                        if (!related) {
+                            if (reportErrors) {
+                                reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop));
+                            }
+                            return 0 /* False */;
+                        }
+                        result &= related;
+                    }
+                }
+                return result;
+            }
+            function indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors) {
+                var related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors);
+                if (!related && reportErrors) {
+                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
+                }
+                return related;
+            }
+            function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors) {
+                if (relation === identityRelation) {
+                    return indexTypesIdenticalTo(source, target, kind);
+                }
+                var targetInfo = getIndexInfoOfType(target, kind);
+                if (!targetInfo || targetInfo.type.flags & 1 /* Any */ && !sourceIsPrimitive) {
+                    // Index signature of type any permits assignment from everything but primitives
+                    return -1 /* True */;
+                }
+                var sourceInfo = getIndexInfoOfType(source, kind) ||
+                    kind === 1 /* Number */ && getIndexInfoOfType(source, 0 /* String */);
+                if (sourceInfo) {
+                    return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
+                }
+                if (isGenericMappedType(source)) {
+                    // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
+                    // if T is related to U.
+                    return kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors);
+                }
+                if (isObjectTypeWithInferableIndex(source)) {
+                    var related = -1 /* True */;
+                    if (kind === 0 /* String */) {
+                        var sourceNumberInfo = getIndexInfoOfType(source, 1 /* Number */);
+                        if (sourceNumberInfo) {
+                            related = indexInfoRelatedTo(sourceNumberInfo, targetInfo, reportErrors);
+                        }
+                    }
+                    if (related) {
+                        related &= eachPropertyRelatedTo(source, targetInfo.type, kind, reportErrors);
+                    }
+                    return related;
+                }
+                if (reportErrors) {
+                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
+                }
+                return 0 /* False */;
+            }
+            function indexTypesIdenticalTo(source, target, indexKind) {
+                var targetInfo = getIndexInfoOfType(target, indexKind);
+                var sourceInfo = getIndexInfoOfType(source, indexKind);
+                if (!sourceInfo && !targetInfo) {
+                    return -1 /* True */;
+                }
+                if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) {
+                    return isRelatedTo(sourceInfo.type, targetInfo.type);
+                }
+                return 0 /* False */;
+            }
+            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
+                if (!sourceSignature.declaration || !targetSignature.declaration) {
+                    return true;
+                }
+                var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
+                var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
+                // A public, protected and private signature is assignable to a private signature.
+                if (targetAccessibility === 8 /* Private */) {
+                    return true;
+                }
+                // A public and protected signature is assignable to a protected signature.
+                if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) {
+                    return true;
+                }
+                // Only a public signature is assignable to public signature.
+                if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) {
+                    return true;
+                }
+                if (reportErrors) {
+                    reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility));
+                }
+                return false;
+            }
+        }
+        // Return a type reference where the source type parameter is replaced with the target marker
+        // type, and flag the result as a marker type reference.
+        function getMarkerTypeReference(type, source, target) {
+            var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; }));
+            result.flags |= 67108864 /* MarkerType */;
+            return result;
+        }
+        // Return an array containing the variance of each type parameter. The variance is effectively
+        // a digest of the type comparisons that occur for each type argument when instantiations of the
+        // generic type are structurally compared. We infer the variance information by comparing
+        // instantiations of the generic type for type arguments with known relations. The function
+        // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function
+        // has been invoked recursively for the given generic type.
+        function getVariances(type) {
+            if (!strictFunctionTypes) {
+                return ts.emptyArray;
+            }
+            var typeParameters = type.typeParameters || ts.emptyArray;
+            var variances = type.variances;
+            if (!variances) {
+                if (type === globalArrayType || type === globalReadonlyArrayType) {
+                    // Arrays are known to be covariant, no need to spend time computing this
+                    variances = [1 /* Covariant */];
+                }
+                else {
+                    // The emptyArray singleton is used to signal a recursive invocation.
+                    type.variances = ts.emptyArray;
+                    variances = [];
+                    for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) {
+                        var tp = typeParameters_1[_i];
+                        // We first compare instantiations where the type parameter is replaced with
+                        // marker types that have a known subtype relationship. From this we can infer
+                        // invariance, covariance, contravariance or bivariance.
+                        var typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType);
+                        var typeWithSub = getMarkerTypeReference(type, tp, markerSubType);
+                        var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) |
+                            (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0);
+                        // If the instantiations appear to be related bivariantly it may be because the
+                        // type parameter is independent (i.e. it isn't witnessed anywhere in the generic
+                        // type). To determine this we compare instantiations where the type parameter is
+                        // replaced with marker types that are known to be unrelated.
+                        if (variance === 3 /* Bivariant */ && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) {
+                            variance = 4 /* Independent */;
+                        }
+                        variances.push(variance);
+                    }
+                }
+                type.variances = variances;
+            }
+            return variances;
+        }
+        // Return true if the given type reference has a 'void' type argument for a covariant type parameter.
+        // See comment at call in recursiveTypeRelatedTo for when this case matters.
+        function hasCovariantVoidArgument(type, variances) {
+            for (var i = 0; i < variances.length; i++) {
+                if (variances[i] === 1 /* Covariant */ && type.typeArguments[i].flags & 1024 /* Void */) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function isUnconstrainedTypeParameter(type) {
+            return type.flags & 16384 /* TypeParameter */ && !getConstraintFromTypeParameter(type);
+        }
+        function isTypeReferenceWithGenericArguments(type) {
+            return getObjectFlags(type) & 4 /* Reference */ && ts.some(type.typeArguments, function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); });
+        }
+        /**
+         * getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
+         *   where A.id=111 and number.id=12
+         */
+        function getTypeReferenceId(type, typeParameters, depth) {
+            if (depth === void 0) { depth = 0; }
+            var result = "" + type.target.id;
+            for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) {
+                var t = _a[_i];
+                if (isUnconstrainedTypeParameter(t)) {
+                    var index = ts.indexOf(typeParameters, t);
+                    if (index < 0) {
+                        index = typeParameters.length;
+                        typeParameters.push(t);
+                    }
+                    result += "=" + index;
+                }
+                else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
+                    result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">";
+                }
+                else {
+                    result += "-" + t.id;
+                }
+            }
+            return result;
+        }
+        /**
+         * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters.
+         * For other cases, the types ids are used.
+         */
+        function getRelationKey(source, target, relation) {
+            if (relation === identityRelation && source.id > target.id) {
+                var temp = source;
+                source = target;
+                target = temp;
+            }
+            if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) {
+                var typeParameters = [];
+                return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters);
+            }
+            return source.id + "," + target.id;
+        }
+        // Invoke the callback for each underlying property symbol of the given symbol and return the first
+        // value that isn't undefined.
+        function forEachProperty(prop, callback) {
+            if (ts.getCheckFlags(prop) & 6 /* Synthetic */) {
+                for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    var p = getPropertyOfType(t, prop.escapedName);
+                    var result = p && forEachProperty(p, callback);
+                    if (result) {
+                        return result;
+                    }
+                }
+                return undefined;
+            }
+            return callback(prop);
+        }
+        // Return the declaring class type of a property or undefined if property not declared in class
+        function getDeclaringClass(prop) {
+            return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined;
+        }
+        // Return true if some underlying source property is declared in a class that derives
+        // from the given base class.
+        function isPropertyInClassDerivedFrom(prop, baseClass) {
+            return forEachProperty(prop, function (sp) {
+                var sourceClass = getDeclaringClass(sp);
+                return sourceClass ? hasBaseType(sourceClass, baseClass) : false;
+            });
+        }
+        // Return true if source property is a valid override of protected parts of target property.
+        function isValidOverrideOf(sourceProp, targetProp) {
+            return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ?
+                !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; });
+        }
+        // Return true if the given class derives from each of the declaring classes of the protected
+        // constituents of the given property.
+        function isClassDerivedFromDeclaringClasses(checkClass, prop) {
+            return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ?
+                !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass;
+        }
+        // Return true if the given type is the constructor type for an abstract class
+        function isAbstractConstructorType(type) {
+            if (getObjectFlags(type) & 16 /* Anonymous */) {
+                var symbol = type.symbol;
+                if (symbol && symbol.flags & 32 /* Class */) {
+                    var declaration = getClassLikeDeclarationOfSymbol(symbol);
+                    if (declaration && ts.hasModifier(declaration, 128 /* Abstract */)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
+        // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
+        // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
+        // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
+        // levels, but unequal at some level beyond that.
+        function isDeeplyNestedType(type, stack, depth) {
+            // We track all object types that have an associated symbol (representing the origin of the type)
+            if (depth >= 5 && type.flags & 32768 /* Object */) {
+                var symbol = type.symbol;
+                if (symbol) {
+                    var count = 0;
+                    for (var i = 0; i < depth; i++) {
+                        var t = stack[i];
+                        if (t.flags & 32768 /* Object */ && t.symbol === symbol) {
+                            count++;
+                            if (count >= 5)
+                                return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+        function isPropertyIdenticalTo(sourceProp, targetProp) {
+            return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */;
+        }
+        function compareProperties(sourceProp, targetProp, compareTypes) {
+            // Two members are considered identical when
+            // - they are public properties with identical names, optionality, and types,
+            // - they are private or protected properties originating in the same declaration and having identical types
+            if (sourceProp === targetProp) {
+                return -1 /* True */;
+            }
+            var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */;
+            var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */;
+            if (sourcePropAccessibility !== targetPropAccessibility) {
+                return 0 /* False */;
+            }
+            if (sourcePropAccessibility) {
+                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
+                    return 0 /* False */;
+                }
+            }
+            else {
+                if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) {
+                    return 0 /* False */;
+                }
+            }
+            if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) {
+                return 0 /* False */;
+            }
+            return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
+        }
+        function isMatchingSignature(source, target, partialMatch) {
+            // A source signature matches a target signature if the two signatures have the same number of required,
+            // optional, and rest parameters.
+            if (source.parameters.length === target.parameters.length &&
+                source.minArgumentCount === target.minArgumentCount &&
+                source.hasRestParameter === target.hasRestParameter) {
+                return true;
+            }
+            // A source signature partially matches a target signature if the target signature has no fewer required
+            // parameters and no more overall parameters than the source signature (where a signature with a rest
+            // parameter is always considered to have more overall parameters than one without).
+            var sourceRestCount = source.hasRestParameter ? 1 : 0;
+            var targetRestCount = target.hasRestParameter ? 1 : 0;
+            if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (sourceRestCount > targetRestCount ||
+                sourceRestCount === targetRestCount && source.parameters.length >= target.parameters.length)) {
+                return true;
+            }
+            return false;
+        }
+        /**
+         * See signatureRelatedTo, compareSignaturesIdentical
+         */
+        function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) {
+            // TODO (drosen): De-duplicate code between related functions.
+            if (source === target) {
+                return -1 /* True */;
+            }
+            if (!(isMatchingSignature(source, target, partialMatch))) {
+                return 0 /* False */;
+            }
+            // Check that the two signatures have the same number of type parameters. We might consider
+            // also checking that any type parameter constraints match, but that would require instantiating
+            // the constraints with a common set of type arguments to get relatable entities in places where
+            // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
+            // particularly as we're comparing erased versions of the signatures below.
+            if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) {
+                return 0 /* False */;
+            }
+            // Spec 1.0 Section 3.8.3 & 3.8.4:
+            // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
+            source = getErasedSignature(source);
+            target = getErasedSignature(target);
+            var result = -1 /* True */;
+            if (!ignoreThisTypes) {
+                var sourceThisType = getThisTypeOfSignature(source);
+                if (sourceThisType) {
+                    var targetThisType = getThisTypeOfSignature(target);
+                    if (targetThisType) {
+                        var related = compareTypes(sourceThisType, targetThisType);
+                        if (!related) {
+                            return 0 /* False */;
+                        }
+                        result &= related;
+                    }
+                }
+            }
+            var targetLen = target.parameters.length;
+            for (var i = 0; i < targetLen; i++) {
+                var s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.parameters[i]);
+                var t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfParameter(target.parameters[i]);
+                var related = compareTypes(s, t);
+                if (!related) {
+                    return 0 /* False */;
+                }
+                result &= related;
+            }
+            if (!ignoreReturnTypes) {
+                result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
+            }
+            return result;
+        }
+        function isRestParameterIndex(signature, parameterIndex) {
+            return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1;
+        }
+        function literalTypesWithSameBaseType(types) {
+            var commonBaseType;
+            for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
+                var t = types_10[_i];
+                var baseType = getBaseTypeOfLiteralType(t);
+                if (!commonBaseType) {
+                    commonBaseType = baseType;
+                }
+                if (baseType === t || baseType !== commonBaseType) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        // When the candidate types are all literal types with the same base type, return a union
+        // of those literal types. Otherwise, return the leftmost type for which no type to the
+        // right is a supertype.
+        function getSupertypeOrUnion(types) {
+            return literalTypesWithSameBaseType(types) ?
+                getUnionType(types) :
+                ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; });
+        }
+        function getCommonSupertype(types) {
+            if (!strictNullChecks) {
+                return getSupertypeOrUnion(types);
+            }
+            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 6144 /* Nullable */); });
+            return primaryTypes.length ?
+                getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 6144 /* Nullable */) :
+                getUnionType(types, /*subtypeReduction*/ true);
+        }
+        // Return the leftmost type for which no type to the right is a subtype.
+        function getCommonSubtype(types) {
+            return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; });
+        }
+        function isArrayType(type) {
+            return getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType;
+        }
+        function isArrayLikeType(type) {
+            // A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
+            // or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
+            return getObjectFlags(type) & 4 /* Reference */ && (type.target === globalArrayType || type.target === globalReadonlyArrayType) ||
+                !(type.flags & 6144 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
+        }
+        function isTupleLikeType(type) {
+            return !!getPropertyOfType(type, "0");
+        }
+        function isUnitType(type) {
+            return !!(type.flags & 6368 /* Unit */);
+        }
+        function isLiteralType(type) {
+            return type.flags & 8 /* Boolean */ ? true :
+                type.flags & 65536 /* Union */ ? type.flags & 256 /* EnumLiteral */ ? true : !ts.forEach(type.types, function (t) { return !isUnitType(t); }) :
+                    isUnitType(type);
+        }
+        function getBaseTypeOfLiteralType(type) {
+            return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
+                type.flags & 32 /* StringLiteral */ ? stringType :
+                    type.flags & 64 /* NumberLiteral */ ? numberType :
+                        type.flags & 128 /* BooleanLiteral */ ? booleanType :
+                            type.flags & 65536 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) :
+                                type;
+        }
+        function getWidenedLiteralType(type) {
+            return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
+                type.flags & 32 /* StringLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? stringType :
+                    type.flags & 64 /* NumberLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? numberType :
+                        type.flags & 128 /* BooleanLiteral */ ? booleanType :
+                            type.flags & 65536 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) :
+                                type;
+        }
+        /**
+         * Check if a Type was written as a tuple type literal.
+         * Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
+         */
+        function isTupleType(type) {
+            return !!(getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */);
+        }
+        function getFalsyFlagsOfTypes(types) {
+            var result = 0;
+            for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
+                var t = types_11[_i];
+                result |= getFalsyFlags(t);
+            }
+            return result;
+        }
+        // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
+        // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
+        // no flags for all other types (including non-falsy literal types).
+        function getFalsyFlags(type) {
+            return type.flags & 65536 /* Union */ ? getFalsyFlagsOfTypes(type.types) :
+                type.flags & 32 /* StringLiteral */ ? type.value === "" ? 32 /* StringLiteral */ : 0 :
+                    type.flags & 64 /* NumberLiteral */ ? type.value === 0 ? 64 /* NumberLiteral */ : 0 :
+                        type.flags & 128 /* BooleanLiteral */ ? type === falseType ? 128 /* BooleanLiteral */ : 0 :
+                            type.flags & 7406 /* PossiblyFalsy */;
+        }
+        function removeDefinitelyFalsyTypes(type) {
+            return getFalsyFlags(type) & 7392 /* DefinitelyFalsy */ ?
+                filterType(type, function (t) { return !(getFalsyFlags(t) & 7392 /* DefinitelyFalsy */); }) :
+                type;
+        }
+        function extractDefinitelyFalsyTypes(type) {
+            return mapType(type, getDefinitelyFalsyPartOfType);
+        }
+        function getDefinitelyFalsyPartOfType(type) {
+            return type.flags & 2 /* String */ ? emptyStringType :
+                type.flags & 4 /* Number */ ? zeroType :
+                    type.flags & 8 /* Boolean */ || type === falseType ? falseType :
+                        type.flags & (1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */) ||
+                            type.flags & 32 /* StringLiteral */ && type.value === "" ||
+                            type.flags & 64 /* NumberLiteral */ && type.value === 0 ? type :
+                            neverType;
+        }
+        /**
+         * Add undefined or null or both to a type if they are missing.
+         * @param type - type to add undefined and/or null to if not present
+         * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
+         */
+        function getNullableType(type, flags) {
+            var missing = (flags & ~type.flags) & (2048 /* Undefined */ | 4096 /* Null */);
+            return missing === 0 ? type :
+                missing === 2048 /* Undefined */ ? getUnionType([type, undefinedType]) :
+                    missing === 4096 /* Null */ ? getUnionType([type, nullType]) :
+                        getUnionType([type, undefinedType, nullType]);
+        }
+        function getNonNullableType(type) {
+            return strictNullChecks ? getTypeWithFacts(type, 524288 /* NEUndefinedOrNull */) : type;
+        }
+        /**
+         * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
+         * with no call or construct signatures.
+         */
+        function isObjectTypeWithInferableIndex(type) {
+            return type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 512 /* ValueModule */)) !== 0 &&
+                getSignaturesOfType(type, 0 /* Call */).length === 0 &&
+                getSignaturesOfType(type, 1 /* Construct */).length === 0;
+        }
+        function createSymbolWithType(source, type) {
+            var symbol = createSymbol(source.flags, source.escapedName);
+            symbol.declarations = source.declarations;
+            symbol.parent = source.parent;
+            symbol.type = type;
+            symbol.target = source;
+            if (source.valueDeclaration) {
+                symbol.valueDeclaration = source.valueDeclaration;
+            }
+            return symbol;
+        }
+        function transformTypeOfMembers(type, f) {
+            var members = ts.createSymbolTable();
+            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
+                var property = _a[_i];
+                var original = getTypeOfSymbol(property);
+                var updated = f(original);
+                members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated));
+            }
+            return members;
+        }
+        /**
+         * If the the provided object literal is subject to the excess properties check,
+         * create a new that is exempt. Recursively mark object literal members as exempt.
+         * Leave signatures alone since they are not subject to the check.
+         */
+        function getRegularTypeOfObjectLiteral(type) {
+            if (!(getObjectFlags(type) & 128 /* ObjectLiteral */ && type.flags & 1048576 /* FreshLiteral */)) {
+                return type;
+            }
+            var regularType = type.regularType;
+            if (regularType) {
+                return regularType;
+            }
+            var resolved = type;
+            var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral);
+            var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo);
+            regularNew.flags = resolved.flags & ~1048576 /* FreshLiteral */;
+            regularNew.objectFlags |= 128 /* ObjectLiteral */;
+            type.regularType = regularNew;
+            return regularNew;
+        }
+        function getWidenedProperty(prop) {
+            var original = getTypeOfSymbol(prop);
+            var widened = getWidenedType(original);
+            return widened === original ? prop : createSymbolWithType(prop, widened);
+        }
+        function getWidenedTypeOfObjectLiteral(type) {
+            var members = ts.createSymbolTable();
+            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
+                var prop = _a[_i];
+                // Since get accessors already widen their return value there is no need to
+                // widen accessor based properties here.
+                members.set(prop.escapedName, prop.flags & 4 /* Property */ ? getWidenedProperty(prop) : prop);
+            }
+            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
+            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
+            return createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
+        }
+        function getWidenedConstituentType(type) {
+            return type.flags & 6144 /* Nullable */ ? type : getWidenedType(type);
+        }
+        function getWidenedType(type) {
+            if (type.flags & 6291456 /* RequiresWidening */) {
+                if (type.flags & 6144 /* Nullable */) {
+                    return anyType;
+                }
+                if (getObjectFlags(type) & 128 /* ObjectLiteral */) {
+                    return getWidenedTypeOfObjectLiteral(type);
+                }
+                if (type.flags & 65536 /* Union */) {
+                    return getUnionType(ts.sameMap(type.types, getWidenedConstituentType));
+                }
+                if (isArrayType(type) || isTupleType(type)) {
+                    return createTypeReference(type.target, ts.sameMap(type.typeArguments, getWidenedType));
+                }
+            }
+            return type;
+        }
+        /**
+         * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
+         * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
+         * getWidenedType. But in some cases getWidenedType is called without reporting errors
+         * (type argument inference is an example).
+         *
+         * The return value indicates whether an error was in fact reported. The particular circumstances
+         * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
+         * an object literal property (arbitrarily deeply), this function reports an error. If no error is
+         * reported, reportImplicitAnyError is a suitable fallback to report a general error.
+         */
+        function reportWideningErrorsInType(type) {
+            var errorReported = false;
+            if (type.flags & 65536 /* Union */) {
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    if (reportWideningErrorsInType(t)) {
+                        errorReported = true;
+                    }
+                }
+            }
+            if (isArrayType(type) || isTupleType(type)) {
+                for (var _b = 0, _c = type.typeArguments; _b < _c.length; _b++) {
+                    var t = _c[_b];
+                    if (reportWideningErrorsInType(t)) {
+                        errorReported = true;
+                    }
+                }
+            }
+            if (getObjectFlags(type) & 128 /* ObjectLiteral */) {
+                for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) {
+                    var p = _e[_d];
+                    var t = getTypeOfSymbol(p);
+                    if (t.flags & 2097152 /* ContainsWideningType */) {
+                        if (!reportWideningErrorsInType(t)) {
+                            error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, ts.symbolName(p), typeToString(getWidenedType(t)));
+                        }
+                        errorReported = true;
+                    }
+                }
+            }
+            return errorReported;
+        }
+        function reportImplicitAnyError(declaration, type) {
+            var typeAsString = typeToString(getWidenedType(type));
+            var diagnostic;
+            switch (declaration.kind) {
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    diagnostic = ts.Diagnostics.Member_0_implicitly_has_an_1_type;
+                    break;
+                case 146 /* Parameter */:
+                    diagnostic = declaration.dotDotDotToken ?
+                        ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type :
+                        ts.Diagnostics.Parameter_0_implicitly_has_an_1_type;
+                    break;
+                case 176 /* BindingElement */:
+                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
+                    break;
+                case 228 /* FunctionDeclaration */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    if (!declaration.name) {
+                        error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
+                        return;
+                    }
+                    diagnostic = ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type;
+                    break;
+                default:
+                    diagnostic = ts.Diagnostics.Variable_0_implicitly_has_an_1_type;
+            }
+            error(declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString);
+        }
+        function reportErrorsFromWidening(declaration, type) {
+            if (produceDiagnostics && noImplicitAny && type.flags & 2097152 /* ContainsWideningType */) {
+                // Report implicit any error within type if possible, otherwise report error on declaration
+                if (!reportWideningErrorsInType(type)) {
+                    reportImplicitAnyError(declaration, type);
+                }
+            }
+        }
+        function forEachMatchingParameterType(source, target, callback) {
+            var sourceMax = source.parameters.length;
+            var targetMax = target.parameters.length;
+            var count;
+            if (source.hasRestParameter && target.hasRestParameter) {
+                count = Math.max(sourceMax, targetMax);
+            }
+            else if (source.hasRestParameter) {
+                count = targetMax;
+            }
+            else if (target.hasRestParameter) {
+                count = sourceMax;
+            }
+            else {
+                count = Math.min(sourceMax, targetMax);
+            }
+            for (var i = 0; i < count; i++) {
+                callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
+            }
+        }
+        function createInferenceContext(signature, flags, compareTypes, baseInferences) {
+            var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo);
+            var context = mapper;
+            context.signature = signature;
+            context.inferences = inferences;
+            context.flags = flags;
+            context.compareTypes = compareTypes || compareTypesAssignable;
+            return context;
+            function mapper(t) {
+                for (var i = 0; i < inferences.length; i++) {
+                    if (t === inferences[i].typeParameter) {
+                        inferences[i].isFixed = true;
+                        return getInferredType(context, i);
+                    }
+                }
+                return t;
+            }
+        }
+        function createInferenceInfo(typeParameter) {
+            return {
+                typeParameter: typeParameter,
+                candidates: undefined,
+                inferredType: undefined,
+                priority: undefined,
+                topLevel: true,
+                isFixed: false
+            };
+        }
+        function cloneInferenceInfo(inference) {
+            return {
+                typeParameter: inference.typeParameter,
+                candidates: inference.candidates && inference.candidates.slice(),
+                inferredType: inference.inferredType,
+                priority: inference.priority,
+                topLevel: inference.topLevel,
+                isFixed: inference.isFixed
+            };
+        }
+        // Return true if the given type could possibly reference a type parameter for which
+        // we perform type inference (i.e. a type parameter of a generic function). We cache
+        // results for union and intersection types for performance reasons.
+        function couldContainTypeVariables(type) {
+            var objectFlags = getObjectFlags(type);
+            return !!(type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ||
+                objectFlags & 4 /* Reference */ && ts.forEach(type.typeArguments, couldContainTypeVariables) ||
+                objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */) ||
+                objectFlags & 32 /* Mapped */ ||
+                type.flags & 196608 /* UnionOrIntersection */ && couldUnionOrIntersectionContainTypeVariables(type));
+        }
+        function couldUnionOrIntersectionContainTypeVariables(type) {
+            if (type.couldContainTypeVariables === undefined) {
+                type.couldContainTypeVariables = ts.forEach(type.types, couldContainTypeVariables);
+            }
+            return type.couldContainTypeVariables;
+        }
+        function isTypeParameterAtTopLevel(type, typeParameter) {
+            return type === typeParameter || type.flags & 196608 /* UnionOrIntersection */ && ts.forEach(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); });
+        }
+        // Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
+        // an object type with the same set of properties as the source type, where the type of each
+        // property is computed by inferring from the source property type to X for the type
+        // variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
+        function inferTypeForHomomorphicMappedType(source, target) {
+            var properties = getPropertiesOfType(source);
+            var indexInfo = getIndexInfoOfType(source, 0 /* String */);
+            if (properties.length === 0 && !indexInfo) {
+                return undefined;
+            }
+            var typeParameter = getIndexedAccessType(getConstraintTypeFromMappedType(target).type, getTypeParameterFromMappedType(target));
+            var inference = createInferenceInfo(typeParameter);
+            var inferences = [inference];
+            var templateType = getTemplateTypeFromMappedType(target);
+            var readonlyMask = target.declaration.readonlyToken ? false : true;
+            var optionalMask = target.declaration.questionToken ? 0 : 16777216 /* Optional */;
+            var members = ts.createSymbolTable();
+            for (var _i = 0, properties_4 = properties; _i < properties_4.length; _i++) {
+                var prop = properties_4[_i];
+                var inferredPropType = inferTargetType(getTypeOfSymbol(prop));
+                if (!inferredPropType) {
+                    return undefined;
+                }
+                var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName);
+                inferredProp.checkFlags = readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0;
+                inferredProp.declarations = prop.declarations;
+                inferredProp.type = inferredPropType;
+                members.set(prop.escapedName, inferredProp);
+            }
+            if (indexInfo) {
+                var inferredIndexType = inferTargetType(indexInfo.type);
+                if (!inferredIndexType) {
+                    return undefined;
+                }
+                indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly);
+            }
+            return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined);
+            function inferTargetType(sourceType) {
+                inference.candidates = undefined;
+                inferTypes(inferences, sourceType, templateType);
+                return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true);
+            }
+        }
+        function getUnmatchedProperty(source, target, requireOptionalProperties) {
+            var properties = getPropertiesOfObjectType(target);
+            for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) {
+                var targetProp = properties_5[_i];
+                if (requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */)) {
+                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
+                    if (!sourceProp) {
+                        return targetProp;
+                    }
+                }
+            }
+            return undefined;
+        }
+        function inferTypes(inferences, originalSource, originalTarget, priority) {
+            if (priority === void 0) { priority = 0; }
+            var symbolStack;
+            var visited;
+            inferFromTypes(originalSource, originalTarget);
+            function inferFromTypes(source, target) {
+                if (!couldContainTypeVariables(target)) {
+                    return;
+                }
+                if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
+                    // Source and target are types originating in the same generic type alias declaration.
+                    // Simply infer from source type arguments to target type arguments.
+                    var sourceTypes = source.aliasTypeArguments;
+                    var targetTypes = target.aliasTypeArguments;
+                    for (var i = 0; i < sourceTypes.length; i++) {
+                        inferFromTypes(sourceTypes[i], targetTypes[i]);
+                    }
+                    return;
+                }
+                if (source.flags & 65536 /* Union */ && target.flags & 65536 /* Union */ && !(source.flags & 256 /* EnumLiteral */ && target.flags & 256 /* EnumLiteral */) ||
+                    source.flags & 131072 /* Intersection */ && target.flags & 131072 /* Intersection */) {
+                    // Source and target are both unions or both intersections. If source and target
+                    // are the same type, just relate each constituent type to itself.
+                    if (source === target) {
+                        for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
+                            var t = _a[_i];
+                            inferFromTypes(t, t);
+                        }
+                        return;
+                    }
+                    // Find each source constituent type that has an identically matching target constituent
+                    // type, and for each such type infer from the type to itself. When inferring from a
+                    // type to itself we effectively find all type parameter occurrences within that type
+                    // and infer themselves as their type arguments. We have special handling for numeric
+                    // and string literals because the number and string types are not represented as unions
+                    // of all their possible values.
+                    var matchingTypes = void 0;
+                    for (var _b = 0, _c = source.types; _b < _c.length; _b++) {
+                        var t = _c[_b];
+                        if (typeIdenticalToSomeType(t, target.types)) {
+                            (matchingTypes || (matchingTypes = [])).push(t);
+                            inferFromTypes(t, t);
+                        }
+                        else if (t.flags & (64 /* NumberLiteral */ | 32 /* StringLiteral */)) {
+                            var b = getBaseTypeOfLiteralType(t);
+                            if (typeIdenticalToSomeType(b, target.types)) {
+                                (matchingTypes || (matchingTypes = [])).push(t, b);
+                            }
+                        }
+                    }
+                    // Next, to improve the quality of inferences, reduce the source and target types by
+                    // removing the identically matched constituents. For example, when inferring from
+                    // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'.
+                    if (matchingTypes) {
+                        source = removeTypesFromUnionOrIntersection(source, matchingTypes);
+                        target = removeTypesFromUnionOrIntersection(target, matchingTypes);
+                    }
+                }
+                if (target.flags & 540672 /* TypeVariable */) {
+                    // If target is a type parameter, make an inference, unless the source type contains
+                    // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
+                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
+                    // it as an inference candidate. Hopefully, a better candidate will come along that does
+                    // not contain anyFunctionType when we come back to this argument for its second round
+                    // of inference. Also, we exclude inferences for silentNeverType which is used as a wildcard
+                    // when constructing types from type parameters that had no inference candidates.
+                    if (source.flags & 8388608 /* ContainsAnyFunctionType */ || source === silentNeverType) {
+                        return;
+                    }
+                    var inference = getInferenceInfoForType(target);
+                    if (inference) {
+                        if (!inference.isFixed) {
+                            if (!inference.candidates || priority < inference.priority) {
+                                inference.candidates = [source];
+                                inference.priority = priority;
+                            }
+                            else if (priority === inference.priority) {
+                                inference.candidates.push(source);
+                            }
+                            if (!(priority & 8 /* ReturnType */) && target.flags & 16384 /* TypeParameter */ && !isTypeParameterAtTopLevel(originalTarget, target)) {
+                                inference.topLevel = false;
+                            }
+                        }
+                        return;
+                    }
+                }
+                else if (getObjectFlags(source) & 4 /* Reference */ && getObjectFlags(target) & 4 /* Reference */ && source.target === target.target) {
+                    // If source and target are references to the same generic type, infer from type arguments
+                    var sourceTypes = source.typeArguments || ts.emptyArray;
+                    var targetTypes = target.typeArguments || ts.emptyArray;
+                    var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
+                    var variances = getVariances(source.target);
+                    for (var i = 0; i < count; i++) {
+                        if (i < variances.length && variances[i] === 2 /* Contravariant */) {
+                            inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
+                        }
+                        else {
+                            inferFromTypes(sourceTypes[i], targetTypes[i]);
+                        }
+                    }
+                }
+                else if (source.flags & 262144 /* Index */ && target.flags & 262144 /* Index */) {
+                    inferFromTypes(source.type, target.type);
+                }
+                else if (source.flags & 524288 /* IndexedAccess */ && target.flags & 524288 /* IndexedAccess */) {
+                    inferFromTypes(source.objectType, target.objectType);
+                    inferFromTypes(source.indexType, target.indexType);
+                }
+                else if (target.flags & 196608 /* UnionOrIntersection */) {
+                    var targetTypes = target.types;
+                    var typeVariableCount = 0;
+                    var typeVariable = void 0;
+                    // First infer to each type in union or intersection that isn't a type variable
+                    for (var _d = 0, targetTypes_3 = targetTypes; _d < targetTypes_3.length; _d++) {
+                        var t = targetTypes_3[_d];
+                        if (getInferenceInfoForType(t)) {
+                            typeVariable = t;
+                            typeVariableCount++;
+                        }
+                        else {
+                            inferFromTypes(source, t);
+                        }
+                    }
+                    // Next, if target containings a single naked type variable, make a secondary inference to that type
+                    // variable. This gives meaningful results for union types in co-variant positions and intersection
+                    // types in contra-variant positions (such as callback parameters).
+                    if (typeVariableCount === 1) {
+                        var savePriority = priority;
+                        priority |= 2 /* NakedTypeVariable */;
+                        inferFromTypes(source, typeVariable);
+                        priority = savePriority;
+                    }
+                }
+                else if (source.flags & 65536 /* Union */) {
+                    // Source is a union or intersection type, infer from each constituent type
+                    var sourceTypes = source.types;
+                    for (var _e = 0, sourceTypes_3 = sourceTypes; _e < sourceTypes_3.length; _e++) {
+                        var sourceType = sourceTypes_3[_e];
+                        inferFromTypes(sourceType, target);
+                    }
+                }
+                else {
+                    source = getApparentType(source);
+                    if (source.flags & (32768 /* Object */ | 131072 /* Intersection */)) {
+                        var key = source.id + "," + target.id;
+                        if (visited && visited.get(key)) {
+                            return;
+                        }
+                        (visited || (visited = ts.createMap())).set(key, true);
+                        // If we are already processing another target type with the same associated symbol (such as
+                        // an instantiation of the same generic type), we do not explore this target as it would yield
+                        // no further inferences. We exclude the static side of classes from this check since it shares
+                        // its symbol with the instance side which would lead to false positives.
+                        var isNonConstructorObject = target.flags & 32768 /* Object */ &&
+                            !(getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */);
+                        var symbol = isNonConstructorObject ? target.symbol : undefined;
+                        if (symbol) {
+                            if (ts.contains(symbolStack, symbol)) {
+                                return;
+                            }
+                            (symbolStack || (symbolStack = [])).push(symbol);
+                            inferFromObjectTypes(source, target);
+                            symbolStack.pop();
+                        }
+                        else {
+                            inferFromObjectTypes(source, target);
+                        }
+                    }
+                }
+            }
+            function inferFromContravariantTypes(source, target) {
+                if (strictFunctionTypes) {
+                    priority ^= 1 /* Contravariant */;
+                    inferFromTypes(source, target);
+                    priority ^= 1 /* Contravariant */;
+                }
+                else {
+                    inferFromTypes(source, target);
+                }
+            }
+            function getInferenceInfoForType(type) {
+                if (type.flags & 540672 /* TypeVariable */) {
+                    for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
+                        var inference = inferences_1[_i];
+                        if (type === inference.typeParameter) {
+                            return inference;
+                        }
+                    }
+                }
+                return undefined;
+            }
+            function inferFromObjectTypes(source, target) {
+                if (isGenericMappedType(source) && isGenericMappedType(target)) {
+                    // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
+                    // from S to T and from X to Y.
+                    inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
+                    inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
+                }
+                if (getObjectFlags(target) & 32 /* Mapped */) {
+                    var constraintType = getConstraintTypeFromMappedType(target);
+                    if (constraintType.flags & 262144 /* Index */) {
+                        // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
+                        // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
+                        // type and then make a secondary inference from that type to T. We make a secondary inference
+                        // such that direct inferences to T get priority over inferences to Partial<T>, for example.
+                        var inference = getInferenceInfoForType(constraintType.type);
+                        if (inference && !inference.isFixed) {
+                            var inferredType = inferTypeForHomomorphicMappedType(source, target);
+                            if (inferredType) {
+                                var savePriority = priority;
+                                priority |= 4 /* MappedType */;
+                                inferFromTypes(inferredType, inference.typeParameter);
+                                priority = savePriority;
+                            }
+                        }
+                        return;
+                    }
+                    if (constraintType.flags & 16384 /* TypeParameter */) {
+                        // We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
+                        // parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
+                        inferFromTypes(getIndexType(source), constraintType);
+                        inferFromTypes(getUnionType(ts.map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(target));
+                        return;
+                    }
+                }
+                // Infer from the members of source and target only if the two types are possibly related. We check
+                // in both directions because we may be inferring for a co-variant or a contra-variant position.
+                if (!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) || !getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false)) {
+                    inferFromProperties(source, target);
+                    inferFromSignatures(source, target, 0 /* Call */);
+                    inferFromSignatures(source, target, 1 /* Construct */);
+                    inferFromIndexTypes(source, target);
+                }
+            }
+            function inferFromProperties(source, target) {
+                var properties = getPropertiesOfObjectType(target);
+                for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) {
+                    var targetProp = properties_6[_i];
+                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
+                    if (sourceProp) {
+                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
+                    }
+                }
+            }
+            function inferFromSignatures(source, target, kind) {
+                var sourceSignatures = getSignaturesOfType(source, kind);
+                var targetSignatures = getSignaturesOfType(target, kind);
+                var sourceLen = sourceSignatures.length;
+                var targetLen = targetSignatures.length;
+                var len = sourceLen < targetLen ? sourceLen : targetLen;
+                for (var i = 0; i < len; i++) {
+                    inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
+                }
+            }
+            function inferFromSignature(source, target) {
+                forEachMatchingParameterType(source, target, inferFromContravariantTypes);
+                if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) {
+                    inferFromTypes(source.typePredicate.type, target.typePredicate.type);
+                }
+                else {
+                    inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
+                }
+            }
+            function inferFromIndexTypes(source, target) {
+                var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */);
+                if (targetStringIndexType) {
+                    var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) ||
+                        getImplicitIndexTypeOfType(source, 0 /* String */);
+                    if (sourceIndexType) {
+                        inferFromTypes(sourceIndexType, targetStringIndexType);
+                    }
+                }
+                var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */);
+                if (targetNumberIndexType) {
+                    var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) ||
+                        getIndexTypeOfType(source, 0 /* String */) ||
+                        getImplicitIndexTypeOfType(source, 1 /* Number */);
+                    if (sourceIndexType) {
+                        inferFromTypes(sourceIndexType, targetNumberIndexType);
+                    }
+                }
+            }
+        }
+        function typeIdenticalToSomeType(type, types) {
+            for (var _i = 0, types_12 = types; _i < types_12.length; _i++) {
+                var t = types_12[_i];
+                if (isTypeIdenticalTo(t, type)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        /**
+         * Return a new union or intersection type computed by removing a given set of types
+         * from a given union or intersection type.
+         */
+        function removeTypesFromUnionOrIntersection(type, typesToRemove) {
+            var reducedTypes = [];
+            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                var t = _a[_i];
+                if (!typeIdenticalToSomeType(t, typesToRemove)) {
+                    reducedTypes.push(t);
+                }
+            }
+            return type.flags & 65536 /* Union */ ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes);
+        }
+        function hasPrimitiveConstraint(type) {
+            var constraint = getConstraintOfTypeParameter(type);
+            return constraint && maybeTypeOfKind(constraint, 8190 /* Primitive */ | 262144 /* Index */);
+        }
+        function getInferredType(context, index) {
+            var inference = context.inferences[index];
+            var inferredType = inference.inferredType;
+            if (!inferredType) {
+                if (inference.candidates) {
+                    // We widen inferred literal types if
+                    // all inferences were made to top-level ocurrences of the type parameter, and
+                    // the type parameter has no constraint or its constraint includes no primitive or literal types, and
+                    // the type parameter was fixed during inference or does not occur at top-level in the return type.
+                    var signature = context.signature;
+                    var widenLiteralTypes = inference.topLevel &&
+                        !hasPrimitiveConstraint(inference.typeParameter) &&
+                        (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
+                    var baseCandidates = widenLiteralTypes ? ts.sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates;
+                    // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
+                    // union types were requested or if all inferences were made from the return type position, infer a
+                    // union type. Otherwise, infer a common supertype.
+                    var unwidenedType = inference.priority & 1 /* Contravariant */ ? getCommonSubtype(baseCandidates) :
+                        context.flags & 1 /* InferUnionTypes */ || inference.priority & 8 /* ReturnType */ ? getUnionType(baseCandidates, /*subtypeReduction*/ true) :
+                            getCommonSupertype(baseCandidates);
+                    inferredType = getWidenedType(unwidenedType);
+                }
+                else if (context.flags & 2 /* NoDefault */) {
+                    // We use silentNeverType as the wildcard that signals no inferences.
+                    inferredType = silentNeverType;
+                }
+                else {
+                    // Infer either the default or the empty object type when no inferences were
+                    // made. It is important to remember that in this case, inference still
+                    // succeeds, meaning there is no error for not having inference candidates. An
+                    // inference error only occurs when there are *conflicting* candidates, i.e.
+                    // candidates with no common supertype.
+                    var defaultType = getDefaultFromTypeParameter(inference.typeParameter);
+                    if (defaultType) {
+                        // Instantiate the default type. Any forward reference to a type
+                        // parameter should be instantiated to the empty object type.
+                        inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context.signature.typeParameters, index), context));
+                    }
+                    else {
+                        inferredType = getDefaultTypeArgumentType(!!(context.flags & 4 /* AnyDefault */));
+                    }
+                }
+                inference.inferredType = inferredType;
+                var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
+                if (constraint) {
+                    var instantiatedConstraint = instantiateType(constraint, context);
+                    if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
+                        inference.inferredType = inferredType = instantiatedConstraint;
+                    }
+                }
+            }
+            return inferredType;
+        }
+        function getDefaultTypeArgumentType(isInJavaScriptFile) {
+            return isInJavaScriptFile ? anyType : emptyObjectType;
+        }
+        function getInferredTypes(context) {
+            var result = [];
+            for (var i = 0; i < context.inferences.length; i++) {
+                result.push(getInferredType(context, i));
+            }
+            return result;
+        }
+        // EXPRESSION TYPE CHECKING
+        function getResolvedSymbol(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedSymbol) {
+                links.resolvedSymbol = !ts.nodeIsMissing(node) &&
+                    resolveName(node, node.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */, ts.Diagnostics.Cannot_find_name_0, node, !ts.isWriteOnlyAccess(node), ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol;
+            }
+            return links.resolvedSymbol;
+        }
+        function isInTypeQuery(node) {
+            // TypeScript 1.0 spec (April 2014): 3.6.3
+            // A type query consists of the keyword typeof followed by an expression.
+            // The expression is restricted to a single identifier or a sequence of identifiers separated by periods
+            return !!ts.findAncestor(node, function (n) { return n.kind === 162 /* TypeQuery */ ? true : n.kind === 71 /* Identifier */ || n.kind === 143 /* QualifiedName */ ? false : "quit"; });
+        }
+        // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
+        // separated by dots). The key consists of the id of the symbol referenced by the
+        // leftmost identifier followed by zero or more property names separated by dots.
+        // The result is undefined if the reference isn't a dotted name. We prefix nodes
+        // occurring in an apparent type position with '@' because the control flow type
+        // of such nodes may be based on the apparent type instead of the declared type.
+        function getFlowCacheKey(node) {
+            if (node.kind === 71 /* Identifier */) {
+                var symbol = getResolvedSymbol(node);
+                return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
+            }
+            if (node.kind === 99 /* ThisKeyword */) {
+                return "0";
+            }
+            if (node.kind === 179 /* PropertyAccessExpression */) {
+                var key = getFlowCacheKey(node.expression);
+                return key && key + "." + ts.idText(node.name);
+            }
+            if (node.kind === 176 /* BindingElement */) {
+                var container = node.parent.parent;
+                var key = container.kind === 176 /* BindingElement */ ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer));
+                var text = getBindingElementNameText(node);
+                var result = key && text && (key + "." + text);
+                return result;
+            }
+            return undefined;
+        }
+        function getBindingElementNameText(element) {
+            if (element.parent.kind === 174 /* ObjectBindingPattern */) {
+                var name = element.propertyName || element.name;
+                switch (name.kind) {
+                    case 71 /* Identifier */:
+                        return ts.idText(name);
+                    case 144 /* ComputedPropertyName */:
+                        return ts.isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
+                    case 9 /* StringLiteral */:
+                    case 8 /* NumericLiteral */:
+                        return name.text;
+                    default:
+                        // Per types, array and object binding patterns remain, however they should never be present if propertyName is not defined
+                        ts.Debug.fail("Unexpected name kind for binding element name");
+                }
+            }
+            else {
+                return "" + element.parent.elements.indexOf(element);
+            }
+        }
+        function isMatchingReference(source, target) {
+            switch (source.kind) {
+                case 71 /* Identifier */:
+                    return target.kind === 71 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) ||
+                        (target.kind === 226 /* VariableDeclaration */ || target.kind === 176 /* BindingElement */) &&
+                            getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target);
+                case 99 /* ThisKeyword */:
+                    return target.kind === 99 /* ThisKeyword */;
+                case 97 /* SuperKeyword */:
+                    return target.kind === 97 /* SuperKeyword */;
+                case 179 /* PropertyAccessExpression */:
+                    return target.kind === 179 /* PropertyAccessExpression */ &&
+                        source.name.escapedText === target.name.escapedText &&
+                        isMatchingReference(source.expression, target.expression);
+                case 176 /* BindingElement */:
+                    if (target.kind !== 179 /* PropertyAccessExpression */)
+                        return false;
+                    var t = target;
+                    if (t.name.escapedText !== getBindingElementNameText(source))
+                        return false;
+                    if (source.parent.parent.kind === 176 /* BindingElement */ && isMatchingReference(source.parent.parent, t.expression)) {
+                        return true;
+                    }
+                    if (source.parent.parent.kind === 226 /* VariableDeclaration */) {
+                        var maybeId = source.parent.parent.initializer;
+                        return maybeId && isMatchingReference(maybeId, t.expression);
+                    }
+            }
+            return false;
+        }
+        function containsMatchingReference(source, target) {
+            while (source.kind === 179 /* PropertyAccessExpression */) {
+                source = source.expression;
+                if (isMatchingReference(source, target)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        // Return true if target is a property access xxx.yyy, source is a property access xxx.zzz, the declared
+        // type of xxx is a union type, and yyy is a property that is possibly a discriminant. We consider a property
+        // a possible discriminant if its type differs in the constituents of containing union type, and if every
+        // choice is a unit type or a union of unit types.
+        function containsMatchingReferenceDiscriminant(source, target) {
+            return target.kind === 179 /* PropertyAccessExpression */ &&
+                containsMatchingReference(source, target.expression) &&
+                isDiscriminantProperty(getDeclaredTypeOfReference(target.expression), target.name.escapedText);
+        }
+        function getDeclaredTypeOfReference(expr) {
+            if (expr.kind === 71 /* Identifier */) {
+                return getTypeOfSymbol(getResolvedSymbol(expr));
+            }
+            if (expr.kind === 179 /* PropertyAccessExpression */) {
+                var type = getDeclaredTypeOfReference(expr.expression);
+                return type && getTypeOfPropertyOfType(type, expr.name.escapedText);
+            }
+            return undefined;
+        }
+        function isDiscriminantProperty(type, name) {
+            if (type && type.flags & 65536 /* Union */) {
+                var prop = getUnionOrIntersectionProperty(type, name);
+                if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) {
+                    if (prop.isDiscriminantProperty === undefined) {
+                        prop.isDiscriminantProperty = prop.checkFlags & 32 /* HasNonUniformType */ && isLiteralType(getTypeOfSymbol(prop));
+                    }
+                    return prop.isDiscriminantProperty;
+                }
+            }
+            return false;
+        }
+        function findSingleDiscriminantProperty(sourceProperties, target) {
+            var result;
+            for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) {
+                var sourceProperty = sourceProperties_2[_i];
+                if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
+                    if (result) {
+                        return undefined;
+                    }
+                    result = sourceProperty;
+                }
+            }
+            return result;
+        }
+        function isOrContainsMatchingReference(source, target) {
+            return isMatchingReference(source, target) || containsMatchingReference(source, target);
+        }
+        function hasMatchingArgument(callExpression, reference) {
+            if (callExpression.arguments) {
+                for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) {
+                    var argument = _a[_i];
+                    if (isOrContainsMatchingReference(reference, argument)) {
+                        return true;
+                    }
+                }
+            }
+            if (callExpression.expression.kind === 179 /* PropertyAccessExpression */ &&
+                isOrContainsMatchingReference(reference, callExpression.expression.expression)) {
+                return true;
+            }
+            return false;
+        }
+        function getFlowNodeId(flow) {
+            if (!flow.id) {
+                flow.id = nextFlowId;
+                nextFlowId++;
+            }
+            return flow.id;
+        }
+        function typeMaybeAssignableTo(source, target) {
+            if (!(source.flags & 65536 /* Union */)) {
+                return isTypeAssignableTo(source, target);
+            }
+            for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
+                var t = _a[_i];
+                if (isTypeAssignableTo(t, target)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
+        // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
+        // we remove type string.
+        function getAssignmentReducedType(declaredType, assignedType) {
+            if (declaredType !== assignedType) {
+                if (assignedType.flags & 8192 /* Never */) {
+                    return assignedType;
+                }
+                var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); });
+                if (!(reducedType.flags & 8192 /* Never */)) {
+                    return reducedType;
+                }
+            }
+            return declaredType;
+        }
+        function getTypeFactsOfTypes(types) {
+            var result = 0 /* None */;
+            for (var _i = 0, types_13 = types; _i < types_13.length; _i++) {
+                var t = types_13[_i];
+                result |= getTypeFacts(t);
+            }
+            return result;
+        }
+        function isFunctionObjectType(type) {
+            // We do a quick check for a "bind" property before performing the more expensive subtype
+            // check. This gives us a quicker out in the common case where an object type is not a function.
+            var resolved = resolveStructuredTypeMembers(type);
+            return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
+                resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType));
+        }
+        function getTypeFacts(type) {
+            var flags = type.flags;
+            if (flags & 2 /* String */) {
+                return strictNullChecks ? 4079361 /* StringStrictFacts */ : 4194049 /* StringFacts */;
+            }
+            if (flags & 32 /* StringLiteral */) {
+                var isEmpty = type.value === "";
+                return strictNullChecks ?
+                    isEmpty ? 3030785 /* EmptyStringStrictFacts */ : 1982209 /* NonEmptyStringStrictFacts */ :
+                    isEmpty ? 3145473 /* EmptyStringFacts */ : 4194049 /* NonEmptyStringFacts */;
+            }
+            if (flags & (4 /* Number */ | 16 /* Enum */)) {
+                return strictNullChecks ? 4079234 /* NumberStrictFacts */ : 4193922 /* NumberFacts */;
+            }
+            if (flags & 64 /* NumberLiteral */) {
+                var isZero = type.value === 0;
+                return strictNullChecks ?
+                    isZero ? 3030658 /* ZeroStrictFacts */ : 1982082 /* NonZeroStrictFacts */ :
+                    isZero ? 3145346 /* ZeroFacts */ : 4193922 /* NonZeroFacts */;
+            }
+            if (flags & 8 /* Boolean */) {
+                return strictNullChecks ? 4078980 /* BooleanStrictFacts */ : 4193668 /* BooleanFacts */;
+            }
+            if (flags & 136 /* BooleanLike */) {
+                return strictNullChecks ?
+                    type === falseType ? 3030404 /* FalseStrictFacts */ : 1981828 /* TrueStrictFacts */ :
+                    type === falseType ? 3145092 /* FalseFacts */ : 4193668 /* TrueFacts */;
+            }
+            if (flags & 32768 /* Object */) {
+                return isFunctionObjectType(type) ?
+                    strictNullChecks ? 6164448 /* FunctionStrictFacts */ : 8376288 /* FunctionFacts */ :
+                    strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */;
+            }
+            if (flags & (1024 /* Void */ | 2048 /* Undefined */)) {
+                return 2457472 /* UndefinedFacts */;
+            }
+            if (flags & 4096 /* Null */) {
+                return 2340752 /* NullFacts */;
+            }
+            if (flags & 512 /* ESSymbol */) {
+                return strictNullChecks ? 1981320 /* SymbolStrictFacts */ : 4193160 /* SymbolFacts */;
+            }
+            if (flags & 16777216 /* NonPrimitive */) {
+                return strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */;
+            }
+            if (flags & 540672 /* TypeVariable */) {
+                return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
+            }
+            if (flags & 196608 /* UnionOrIntersection */) {
+                return getTypeFactsOfTypes(type.types);
+            }
+            return 8388607 /* All */;
+        }
+        function getTypeWithFacts(type, include) {
+            if (type.flags & 524288 /* IndexedAccess */) {
+                // TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to
+                //  - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior
+                var baseConstraint = getBaseConstraintOfType(type) || emptyObjectType;
+                var result = filterType(baseConstraint, function (t) { return (getTypeFacts(t) & include) !== 0; });
+                if (result !== baseConstraint) {
+                    return result;
+                }
+                return type;
+            }
+            return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; });
+        }
+        function getTypeWithDefault(type, defaultExpression) {
+            if (defaultExpression) {
+                var defaultType = getTypeOfExpression(defaultExpression);
+                return getUnionType([getTypeWithFacts(type, 131072 /* NEUndefined */), defaultType]);
+            }
+            return type;
+        }
+        function getTypeOfDestructuredProperty(type, name) {
+            var text = ts.getTextOfPropertyName(name);
+            return getTypeOfPropertyOfType(type, text) ||
+                isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) ||
+                getIndexTypeOfType(type, 0 /* String */) ||
+                unknownType;
+        }
+        function getTypeOfDestructuredArrayElement(type, index) {
+            return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index) ||
+                checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) ||
+                unknownType;
+        }
+        function getTypeOfDestructuredSpreadExpression(type) {
+            return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType);
+        }
+        function getAssignedTypeOfBinaryExpression(node) {
+            var isDestructuringDefaultAssignment = node.parent.kind === 177 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) ||
+                node.parent.kind === 261 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent);
+            return isDestructuringDefaultAssignment ?
+                getTypeWithDefault(getAssignedType(node), node.right) :
+                getTypeOfExpression(node.right);
+        }
+        function isDestructuringAssignmentTarget(parent) {
+            return parent.parent.kind === 194 /* BinaryExpression */ && parent.parent.left === parent ||
+                parent.parent.kind === 216 /* ForOfStatement */ && parent.parent.initializer === parent;
+        }
+        function getAssignedTypeOfArrayLiteralElement(node, element) {
+            return getTypeOfDestructuredArrayElement(getAssignedType(node), ts.indexOf(node.elements, element));
+        }
+        function getAssignedTypeOfSpreadExpression(node) {
+            return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent));
+        }
+        function getAssignedTypeOfPropertyAssignment(node) {
+            return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name);
+        }
+        function getAssignedTypeOfShorthandPropertyAssignment(node) {
+            return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer);
+        }
+        function getAssignedType(node) {
+            var parent = node.parent;
+            switch (parent.kind) {
+                case 215 /* ForInStatement */:
+                    return stringType;
+                case 216 /* ForOfStatement */:
+                    return checkRightHandSideOfForOf(parent.expression, parent.awaitModifier) || unknownType;
+                case 194 /* BinaryExpression */:
+                    return getAssignedTypeOfBinaryExpression(parent);
+                case 188 /* DeleteExpression */:
+                    return undefinedType;
+                case 177 /* ArrayLiteralExpression */:
+                    return getAssignedTypeOfArrayLiteralElement(parent, node);
+                case 198 /* SpreadElement */:
+                    return getAssignedTypeOfSpreadExpression(parent);
+                case 261 /* PropertyAssignment */:
+                    return getAssignedTypeOfPropertyAssignment(parent);
+                case 262 /* ShorthandPropertyAssignment */:
+                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
+            }
+            return unknownType;
+        }
+        function getInitialTypeOfBindingElement(node) {
+            var pattern = node.parent;
+            var parentType = getInitialType(pattern.parent);
+            var type = pattern.kind === 174 /* ObjectBindingPattern */ ?
+                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
+                !node.dotDotDotToken ?
+                    getTypeOfDestructuredArrayElement(parentType, ts.indexOf(pattern.elements, node)) :
+                    getTypeOfDestructuredSpreadExpression(parentType);
+            return getTypeWithDefault(type, node.initializer);
+        }
+        function getTypeOfInitializer(node) {
+            // Return the cached type if one is available. If the type of the variable was inferred
+            // from its initializer, we'll already have cached the type. Otherwise we compute it now
+            // without caching such that transient types are reflected.
+            var links = getNodeLinks(node);
+            return links.resolvedType || getTypeOfExpression(node);
+        }
+        function getInitialTypeOfVariableDeclaration(node) {
+            if (node.initializer) {
+                return getTypeOfInitializer(node.initializer);
+            }
+            if (node.parent.parent.kind === 215 /* ForInStatement */) {
+                return stringType;
+            }
+            if (node.parent.parent.kind === 216 /* ForOfStatement */) {
+                return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || unknownType;
+            }
+            return unknownType;
+        }
+        function getInitialType(node) {
+            return node.kind === 226 /* VariableDeclaration */ ?
+                getInitialTypeOfVariableDeclaration(node) :
+                getInitialTypeOfBindingElement(node);
+        }
+        function getInitialOrAssignedType(node) {
+            return node.kind === 226 /* VariableDeclaration */ || node.kind === 176 /* BindingElement */ ?
+                getInitialType(node) :
+                getAssignedType(node);
+        }
+        function isEmptyArrayAssignment(node) {
+            return node.kind === 226 /* VariableDeclaration */ && node.initializer &&
+                isEmptyArrayLiteral(node.initializer) ||
+                node.kind !== 176 /* BindingElement */ && node.parent.kind === 194 /* BinaryExpression */ &&
+                    isEmptyArrayLiteral(node.parent.right);
+        }
+        function getReferenceCandidate(node) {
+            switch (node.kind) {
+                case 185 /* ParenthesizedExpression */:
+                    return getReferenceCandidate(node.expression);
+                case 194 /* BinaryExpression */:
+                    switch (node.operatorToken.kind) {
+                        case 58 /* EqualsToken */:
+                            return getReferenceCandidate(node.left);
+                        case 26 /* CommaToken */:
+                            return getReferenceCandidate(node.right);
+                    }
+            }
+            return node;
+        }
+        function getReferenceRoot(node) {
+            var parent = node.parent;
+            return parent.kind === 185 /* ParenthesizedExpression */ ||
+                parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */ && parent.left === node ||
+                parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 26 /* CommaToken */ && parent.right === node ?
+                getReferenceRoot(parent) : node;
+        }
+        function getTypeOfSwitchClause(clause) {
+            if (clause.kind === 257 /* CaseClause */) {
+                var caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
+                return isUnitType(caseType) ? caseType : undefined;
+            }
+            return neverType;
+        }
+        function getSwitchClauseTypes(switchStatement) {
+            var links = getNodeLinks(switchStatement);
+            if (!links.switchTypes) {
+                // If all case clauses specify expressions that have unit types, we return an array
+                // of those unit types. Otherwise we return an empty array.
+                links.switchTypes = [];
+                for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
+                    var clause = _a[_i];
+                    var type = getTypeOfSwitchClause(clause);
+                    if (type === undefined) {
+                        return links.switchTypes = ts.emptyArray;
+                    }
+                    links.switchTypes.push(type);
+                }
+            }
+            return links.switchTypes;
+        }
+        function eachTypeContainedIn(source, types) {
+            return source.flags & 65536 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
+        }
+        function isTypeSubsetOf(source, target) {
+            return source === target || target.flags & 65536 /* Union */ && isTypeSubsetOfUnion(source, target);
+        }
+        function isTypeSubsetOfUnion(source, target) {
+            if (source.flags & 65536 /* Union */) {
+                for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    if (!containsType(target.types, t)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            if (source.flags & 256 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) {
+                return true;
+            }
+            return containsType(target.types, source);
+        }
+        function forEachType(type, f) {
+            return type.flags & 65536 /* Union */ ? ts.forEach(type.types, f) : f(type);
+        }
+        function filterType(type, f) {
+            if (type.flags & 65536 /* Union */) {
+                var types = type.types;
+                var filtered = ts.filter(types, f);
+                return filtered === types ? type : getUnionTypeFromSortedList(filtered);
+            }
+            return f(type) ? type : neverType;
+        }
+        // Apply a mapping function to a type and return the resulting type. If the source type
+        // is a union type, the mapping function is applied to each constituent type and a union
+        // of the resulting types is returned.
+        function mapType(type, mapper) {
+            if (!(type.flags & 65536 /* Union */)) {
+                return mapper(type);
+            }
+            var types = type.types;
+            var mappedType;
+            var mappedTypes;
+            for (var _i = 0, types_14 = types; _i < types_14.length; _i++) {
+                var current = types_14[_i];
+                var t = mapper(current);
+                if (t) {
+                    if (!mappedType) {
+                        mappedType = t;
+                    }
+                    else if (!mappedTypes) {
+                        mappedTypes = [mappedType, t];
+                    }
+                    else {
+                        mappedTypes.push(t);
+                    }
+                }
+            }
+            return mappedTypes ? getUnionType(mappedTypes) : mappedType;
+        }
+        function extractTypesOfKind(type, kind) {
+            return filterType(type, function (t) { return (t.flags & kind) !== 0; });
+        }
+        // Return a new type in which occurrences of the string and number primitive types in
+        // typeWithPrimitives have been replaced with occurrences of string literals and numeric
+        // literals in typeWithLiterals, respectively.
+        function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) {
+            if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 32 /* StringLiteral */) ||
+                isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 64 /* NumberLiteral */)) {
+                return mapType(typeWithPrimitives, function (t) {
+                    return t.flags & 2 /* String */ ? extractTypesOfKind(typeWithLiterals, 2 /* String */ | 32 /* StringLiteral */) :
+                        t.flags & 4 /* Number */ ? extractTypesOfKind(typeWithLiterals, 4 /* Number */ | 64 /* NumberLiteral */) :
+                            t;
+                });
+            }
+            return typeWithPrimitives;
+        }
+        function isIncomplete(flowType) {
+            return flowType.flags === 0;
+        }
+        function getTypeFromFlowType(flowType) {
+            return flowType.flags === 0 ? flowType.type : flowType;
+        }
+        function createFlowType(type, incomplete) {
+            return incomplete ? { flags: 0, type: type } : type;
+        }
+        // An evolving array type tracks the element types that have so far been seen in an
+        // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
+        // array types are ultimately converted into manifest array types (using getFinalArrayType)
+        // and never escape the getFlowTypeOfReference function.
+        function createEvolvingArrayType(elementType) {
+            var result = createObjectType(256 /* EvolvingArray */);
+            result.elementType = elementType;
+            return result;
+        }
+        function getEvolvingArrayType(elementType) {
+            return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
+        }
+        // When adding evolving array element types we do not perform subtype reduction. Instead,
+        // we defer subtype reduction until the evolving array type is finalized into a manifest
+        // array type.
+        function addEvolvingArrayElementType(evolvingArrayType, node) {
+            var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
+            return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
+        }
+        function createFinalArrayType(elementType) {
+            return elementType.flags & 8192 /* Never */ ?
+                autoArrayType :
+                createArrayType(elementType.flags & 65536 /* Union */ ?
+                    getUnionType(elementType.types, /*subtypeReduction*/ true) :
+                    elementType);
+        }
+        // We perform subtype reduction upon obtaining the final array type from an evolving array type.
+        function getFinalArrayType(evolvingArrayType) {
+            return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
+        }
+        function finalizeEvolvingArrayType(type) {
+            return getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type;
+        }
+        function getElementTypeOfEvolvingArrayType(type) {
+            return getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType;
+        }
+        function isEvolvingArrayTypeList(types) {
+            var hasEvolvingArrayType = false;
+            for (var _i = 0, types_15 = types; _i < types_15.length; _i++) {
+                var t = types_15[_i];
+                if (!(t.flags & 8192 /* Never */)) {
+                    if (!(getObjectFlags(t) & 256 /* EvolvingArray */)) {
+                        return false;
+                    }
+                    hasEvolvingArrayType = true;
+                }
+            }
+            return hasEvolvingArrayType;
+        }
+        // At flow control branch or loop junctions, if the type along every antecedent code path
+        // is an evolving array type, we construct a combined evolving array type. Otherwise we
+        // finalize all evolving array types.
+        function getUnionOrEvolvingArrayType(types, subtypeReduction) {
+            return isEvolvingArrayTypeList(types) ?
+                getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) :
+                getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
+        }
+        // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
+        // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
+        function isEvolvingArrayOperationTarget(node) {
+            var root = getReferenceRoot(node);
+            var parent = root.parent;
+            var isLengthPushOrUnshift = parent.kind === 179 /* PropertyAccessExpression */ && (parent.name.escapedText === "length" ||
+                parent.parent.kind === 181 /* CallExpression */ && ts.isPushOrUnshiftIdentifier(parent.name));
+            var isElementAssignment = parent.kind === 180 /* ElementAccessExpression */ &&
+                parent.expression === root &&
+                parent.parent.kind === 194 /* BinaryExpression */ &&
+                parent.parent.operatorToken.kind === 58 /* EqualsToken */ &&
+                parent.parent.left === parent &&
+                !ts.isAssignmentTarget(parent.parent) &&
+                isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */);
+            return isLengthPushOrUnshift || isElementAssignment;
+        }
+        function maybeTypePredicateCall(node) {
+            var links = getNodeLinks(node);
+            if (links.maybeTypePredicate === undefined) {
+                links.maybeTypePredicate = getMaybeTypePredicate(node);
+            }
+            return links.maybeTypePredicate;
+        }
+        function getMaybeTypePredicate(node) {
+            if (node.expression.kind !== 97 /* SuperKeyword */) {
+                var funcType = checkNonNullExpression(node.expression);
+                if (funcType !== silentNeverType) {
+                    var apparentType = getApparentType(funcType);
+                    if (apparentType !== unknownType) {
+                        var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
+                        return !!ts.forEach(callSignatures, function (sig) { return sig.typePredicate; });
+                    }
+                }
+            }
+            return false;
+        }
+        function reportFlowControlError(node) {
+            var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock);
+            var sourceFile = ts.getSourceFileOfNode(node);
+            var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
+            diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
+        }
+        function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) {
+            if (initialType === void 0) { initialType = declaredType; }
+            var key;
+            var flowDepth = 0;
+            if (flowAnalysisDisabled) {
+                return unknownType;
+            }
+            if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 17810175 /* Narrowable */)) {
+                return declaredType;
+            }
+            var sharedFlowStart = sharedFlowCount;
+            var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
+            sharedFlowCount = sharedFlowStart;
+            // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
+            // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
+            // on empty arrays are possible without implicit any errors and new element types can be inferred without
+            // type mismatch errors.
+            var resultType = getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
+            if (reference.parent.kind === 203 /* NonNullExpression */ && getTypeWithFacts(resultType, 524288 /* NEUndefinedOrNull */).flags & 8192 /* Never */) {
+                return declaredType;
+            }
+            return resultType;
+            function getTypeAtFlowNode(flow) {
+                if (flowDepth === 2500) {
+                    // We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error
+                    // and disable further control flow analysis in the containing function or module body.
+                    flowAnalysisDisabled = true;
+                    reportFlowControlError(reference);
+                    return unknownType;
+                }
+                flowDepth++;
+                while (true) {
+                    var flags = flow.flags;
+                    if (flags & 1024 /* Shared */) {
+                        // We cache results of flow type resolution for shared nodes that were previously visited in
+                        // the same getFlowTypeOfReference invocation. A node is considered shared when it is the
+                        // antecedent of more than one node.
+                        for (var i = sharedFlowStart; i < sharedFlowCount; i++) {
+                            if (sharedFlowNodes[i] === flow) {
+                                flowDepth--;
+                                return sharedFlowTypes[i];
+                            }
+                        }
+                    }
+                    var type = void 0;
+                    if (flags & 4096 /* AfterFinally */) {
+                        // block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement
+                        flow.locked = true;
+                        type = getTypeAtFlowNode(flow.antecedent);
+                        flow.locked = false;
+                    }
+                    else if (flags & 2048 /* PreFinally */) {
+                        // locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel
+                        // so here just redirect to antecedent
+                        flow = flow.antecedent;
+                        continue;
+                    }
+                    else if (flags & 16 /* Assignment */) {
+                        type = getTypeAtFlowAssignment(flow);
+                        if (!type) {
+                            flow = flow.antecedent;
+                            continue;
+                        }
+                    }
+                    else if (flags & 96 /* Condition */) {
+                        type = getTypeAtFlowCondition(flow);
+                    }
+                    else if (flags & 128 /* SwitchClause */) {
+                        type = getTypeAtSwitchClause(flow);
+                    }
+                    else if (flags & 12 /* Label */) {
+                        if (flow.antecedents.length === 1) {
+                            flow = flow.antecedents[0];
+                            continue;
+                        }
+                        type = flags & 4 /* BranchLabel */ ?
+                            getTypeAtFlowBranchLabel(flow) :
+                            getTypeAtFlowLoopLabel(flow);
+                    }
+                    else if (flags & 256 /* ArrayMutation */) {
+                        type = getTypeAtFlowArrayMutation(flow);
+                        if (!type) {
+                            flow = flow.antecedent;
+                            continue;
+                        }
+                    }
+                    else if (flags & 2 /* Start */) {
+                        // Check if we should continue with the control flow of the containing function.
+                        var container = flow.container;
+                        if (container && container !== flowContainer && reference.kind !== 179 /* PropertyAccessExpression */ && reference.kind !== 99 /* ThisKeyword */) {
+                            flow = container.flowNode;
+                            continue;
+                        }
+                        // At the top of the flow we have the initial type.
+                        type = initialType;
+                    }
+                    else {
+                        // Unreachable code errors are reported in the binding phase. Here we
+                        // simply return the non-auto declared type to reduce follow-on errors.
+                        type = convertAutoToAny(declaredType);
+                    }
+                    if (flags & 1024 /* Shared */) {
+                        // Record visited node and the associated type in the cache.
+                        sharedFlowNodes[sharedFlowCount] = flow;
+                        sharedFlowTypes[sharedFlowCount] = type;
+                        sharedFlowCount++;
+                    }
+                    flowDepth--;
+                    return type;
+                }
+            }
+            function getTypeAtFlowAssignment(flow) {
+                var node = flow.node;
+                // Assignments only narrow the computed type if the declared type is a union type. Thus, we
+                // only need to evaluate the assigned type if the declared type is a union type.
+                if (isMatchingReference(reference, node)) {
+                    if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) {
+                        var flowType = getTypeAtFlowNode(flow.antecedent);
+                        return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
+                    }
+                    if (declaredType === autoType || declaredType === autoArrayType) {
+                        if (isEmptyArrayAssignment(node)) {
+                            return getEvolvingArrayType(neverType);
+                        }
+                        var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node));
+                        return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
+                    }
+                    if (declaredType.flags & 65536 /* Union */) {
+                        return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node));
+                    }
+                    return declaredType;
+                }
+                // We didn't have a direct match. However, if the reference is a dotted name, this
+                // may be an assignment to a left hand part of the reference. For example, for a
+                // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
+                // return the declared type.
+                if (containsMatchingReference(reference, node)) {
+                    return declaredType;
+                }
+                // Assignment doesn't affect reference
+                return undefined;
+            }
+            function getTypeAtFlowArrayMutation(flow) {
+                if (declaredType === autoType || declaredType === autoArrayType) {
+                    var node = flow.node;
+                    var expr = node.kind === 181 /* CallExpression */ ?
+                        node.expression.expression :
+                        node.left.expression;
+                    if (isMatchingReference(reference, getReferenceCandidate(expr))) {
+                        var flowType = getTypeAtFlowNode(flow.antecedent);
+                        var type = getTypeFromFlowType(flowType);
+                        if (getObjectFlags(type) & 256 /* EvolvingArray */) {
+                            var evolvedType_1 = type;
+                            if (node.kind === 181 /* CallExpression */) {
+                                for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
+                                    var arg = _a[_i];
+                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg);
+                                }
+                            }
+                            else {
+                                var indexType = getTypeOfExpression(node.left.argumentExpression);
+                                if (isTypeAssignableToKind(indexType, 84 /* NumberLike */)) {
+                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right);
+                                }
+                            }
+                            return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType));
+                        }
+                        return flowType;
+                    }
+                }
+                return undefined;
+            }
+            function getTypeAtFlowCondition(flow) {
+                var flowType = getTypeAtFlowNode(flow.antecedent);
+                var type = getTypeFromFlowType(flowType);
+                if (type.flags & 8192 /* Never */) {
+                    return flowType;
+                }
+                // If we have an antecedent type (meaning we're reachable in some way), we first
+                // attempt to narrow the antecedent type. If that produces the never type, and if
+                // the antecedent type is incomplete (i.e. a transient type in a loop), then we
+                // take the type guard as an indication that control *could* reach here once we
+                // have the complete type. We proceed by switching to the silent never type which
+                // doesn't report errors when operators are applied to it. Note that this is the
+                // *only* place a silent never type is ever generated.
+                var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
+                var nonEvolvingType = finalizeEvolvingArrayType(type);
+                var narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue);
+                if (narrowedType === nonEvolvingType) {
+                    return flowType;
+                }
+                var incomplete = isIncomplete(flowType);
+                var resultType = incomplete && narrowedType.flags & 8192 /* Never */ ? silentNeverType : narrowedType;
+                return createFlowType(resultType, incomplete);
+            }
+            function getTypeAtSwitchClause(flow) {
+                var flowType = getTypeAtFlowNode(flow.antecedent);
+                var type = getTypeFromFlowType(flowType);
+                var expr = flow.switchStatement.expression;
+                if (isMatchingReference(reference, expr)) {
+                    type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
+                }
+                else if (isMatchingReferenceDiscriminant(expr, type)) {
+                    type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); });
+                }
+                return createFlowType(type, isIncomplete(flowType));
+            }
+            function getTypeAtFlowBranchLabel(flow) {
+                var antecedentTypes = [];
+                var subtypeReduction = false;
+                var seenIncomplete = false;
+                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
+                    var antecedent = _a[_i];
+                    if (antecedent.flags & 2048 /* PreFinally */ && antecedent.lock.locked) {
+                        // if flow correspond to branch from pre-try to finally and this branch is locked - this means that
+                        // we initially have started following the flow outside the finally block.
+                        // in this case we should ignore this branch.
+                        continue;
+                    }
+                    var flowType = getTypeAtFlowNode(antecedent);
+                    var type = getTypeFromFlowType(flowType);
+                    // If the type at a particular antecedent path is the declared type and the
+                    // reference is known to always be assigned (i.e. when declared and initial types
+                    // are the same), there is no reason to process more antecedents since the only
+                    // possible outcome is subtypes that will be removed in the final union type anyway.
+                    if (type === declaredType && declaredType === initialType) {
+                        return type;
+                    }
+                    ts.pushIfUnique(antecedentTypes, type);
+                    // If an antecedent type is not a subset of the declared type, we need to perform
+                    // subtype reduction. This happens when a "foreign" type is injected into the control
+                    // flow using the instanceof operator or a user defined type predicate.
+                    if (!isTypeSubsetOf(type, declaredType)) {
+                        subtypeReduction = true;
+                    }
+                    if (isIncomplete(flowType)) {
+                        seenIncomplete = true;
+                    }
+                }
+                return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete);
+            }
+            function getTypeAtFlowLoopLabel(flow) {
+                // If we have previously computed the control flow type for the reference at
+                // this flow loop junction, return the cached type.
+                var id = getFlowNodeId(flow);
+                var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap());
+                if (!key) {
+                    key = getFlowCacheKey(reference);
+                    // No cache key is generated when binding patterns are in unnarrowable situations
+                    if (!key) {
+                        return declaredType;
+                    }
+                }
+                var cached = cache.get(key);
+                if (cached) {
+                    return cached;
+                }
+                // If this flow loop junction and reference are already being processed, return
+                // the union of the types computed for each branch so far, marked as incomplete.
+                // It is possible to see an empty array in cases where loops are nested and the
+                // back edge of the outer loop reaches an inner loop that is already being analyzed.
+                // In such cases we restart the analysis of the inner loop, which will then see
+                // a non-empty in-process array for the outer loop and eventually terminate because
+                // the first antecedent of a loop junction is always the non-looping control flow
+                // path that leads to the top.
+                for (var i = flowLoopStart; i < flowLoopCount; i++) {
+                    if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
+                        return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true);
+                    }
+                }
+                // Add the flow loop junction and reference to the in-process stack and analyze
+                // each antecedent code path.
+                var antecedentTypes = [];
+                var subtypeReduction = false;
+                var firstAntecedentType;
+                flowLoopNodes[flowLoopCount] = flow;
+                flowLoopKeys[flowLoopCount] = key;
+                flowLoopTypes[flowLoopCount] = antecedentTypes;
+                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
+                    var antecedent = _a[_i];
+                    flowLoopCount++;
+                    var flowType = getTypeAtFlowNode(antecedent);
+                    flowLoopCount--;
+                    if (!firstAntecedentType) {
+                        firstAntecedentType = flowType;
+                    }
+                    var type = getTypeFromFlowType(flowType);
+                    // If we see a value appear in the cache it is a sign that control flow  analysis
+                    // was restarted and completed by checkExpressionCached. We can simply pick up
+                    // the resulting type and bail out.
+                    var cached_1 = cache.get(key);
+                    if (cached_1) {
+                        return cached_1;
+                    }
+                    ts.pushIfUnique(antecedentTypes, type);
+                    // If an antecedent type is not a subset of the declared type, we need to perform
+                    // subtype reduction. This happens when a "foreign" type is injected into the control
+                    // flow using the instanceof operator or a user defined type predicate.
+                    if (!isTypeSubsetOf(type, declaredType)) {
+                        subtypeReduction = true;
+                    }
+                    // If the type at a particular antecedent path is the declared type there is no
+                    // reason to process more antecedents since the only possible outcome is subtypes
+                    // that will be removed in the final union type anyway.
+                    if (type === declaredType) {
+                        break;
+                    }
+                }
+                // The result is incomplete if the first antecedent (the non-looping control flow path)
+                // is incomplete.
+                var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction);
+                if (isIncomplete(firstAntecedentType)) {
+                    return createFlowType(result, /*incomplete*/ true);
+                }
+                cache.set(key, result);
+                return result;
+            }
+            function isMatchingReferenceDiscriminant(expr, computedType) {
+                return expr.kind === 179 /* PropertyAccessExpression */ &&
+                    computedType.flags & 65536 /* Union */ &&
+                    isMatchingReference(reference, expr.expression) &&
+                    isDiscriminantProperty(computedType, expr.name.escapedText);
+            }
+            function narrowTypeByDiscriminant(type, propAccess, narrowType) {
+                var propName = propAccess.name.escapedText;
+                var propType = getTypeOfPropertyOfType(type, propName);
+                var narrowedPropType = propType && narrowType(propType);
+                return propType === narrowedPropType ? type : filterType(type, function (t) { return isTypeComparableTo(getTypeOfPropertyOfType(t, propName), narrowedPropType); });
+            }
+            function narrowTypeByTruthiness(type, expr, assumeTrue) {
+                if (isMatchingReference(reference, expr)) {
+                    return getTypeWithFacts(type, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */);
+                }
+                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
+                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */); });
+                }
+                if (containsMatchingReferenceDiscriminant(reference, expr)) {
+                    return declaredType;
+                }
+                return type;
+            }
+            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
+                switch (expr.operatorToken.kind) {
+                    case 58 /* EqualsToken */:
+                        return narrowTypeByTruthiness(type, expr.left, assumeTrue);
+                    case 32 /* EqualsEqualsToken */:
+                    case 33 /* ExclamationEqualsToken */:
+                    case 34 /* EqualsEqualsEqualsToken */:
+                    case 35 /* ExclamationEqualsEqualsToken */:
+                        var operator_1 = expr.operatorToken.kind;
+                        var left_1 = getReferenceCandidate(expr.left);
+                        var right_1 = getReferenceCandidate(expr.right);
+                        if (left_1.kind === 189 /* TypeOfExpression */ && right_1.kind === 9 /* StringLiteral */) {
+                            return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue);
+                        }
+                        if (right_1.kind === 189 /* TypeOfExpression */ && left_1.kind === 9 /* StringLiteral */) {
+                            return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue);
+                        }
+                        if (isMatchingReference(reference, left_1)) {
+                            return narrowTypeByEquality(type, operator_1, right_1, assumeTrue);
+                        }
+                        if (isMatchingReference(reference, right_1)) {
+                            return narrowTypeByEquality(type, operator_1, left_1, assumeTrue);
+                        }
+                        if (isMatchingReferenceDiscriminant(left_1, declaredType)) {
+                            return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); });
+                        }
+                        if (isMatchingReferenceDiscriminant(right_1, declaredType)) {
+                            return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); });
+                        }
+                        if (containsMatchingReferenceDiscriminant(reference, left_1) || containsMatchingReferenceDiscriminant(reference, right_1)) {
+                            return declaredType;
+                        }
+                        break;
+                    case 93 /* InstanceOfKeyword */:
+                        return narrowTypeByInstanceof(type, expr, assumeTrue);
+                    case 26 /* CommaToken */:
+                        return narrowType(type, expr.right, assumeTrue);
+                }
+                return type;
+            }
+            function narrowTypeByEquality(type, operator, value, assumeTrue) {
+                if (type.flags & 1 /* Any */) {
+                    return type;
+                }
+                if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) {
+                    assumeTrue = !assumeTrue;
+                }
+                var valueType = getTypeOfExpression(value);
+                if (valueType.flags & 6144 /* Nullable */) {
+                    if (!strictNullChecks) {
+                        return type;
+                    }
+                    var doubleEquals = operator === 32 /* EqualsEqualsToken */ || operator === 33 /* ExclamationEqualsToken */;
+                    var facts = doubleEquals ?
+                        assumeTrue ? 65536 /* EQUndefinedOrNull */ : 524288 /* NEUndefinedOrNull */ :
+                        value.kind === 95 /* NullKeyword */ ?
+                            assumeTrue ? 32768 /* EQNull */ : 262144 /* NENull */ :
+                            assumeTrue ? 16384 /* EQUndefined */ : 131072 /* NEUndefined */;
+                    return getTypeWithFacts(type, facts);
+                }
+                if (type.flags & 16810497 /* NotUnionOrUnit */) {
+                    return type;
+                }
+                if (assumeTrue) {
+                    var narrowedType = filterType(type, function (t) { return areTypesComparable(t, valueType); });
+                    return narrowedType.flags & 8192 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
+                }
+                if (isUnitType(valueType)) {
+                    var regularType_1 = getRegularTypeOfLiteralType(valueType);
+                    return filterType(type, function (t) { return getRegularTypeOfLiteralType(t) !== regularType_1; });
+                }
+                return type;
+            }
+            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
+                // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands
+                var target = getReferenceCandidate(typeOfExpr.expression);
+                if (!isMatchingReference(reference, target)) {
+                    // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
+                    // narrowed type of 'y' to its declared type.
+                    if (containsMatchingReference(reference, target)) {
+                        return declaredType;
+                    }
+                    return type;
+                }
+                if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) {
+                    assumeTrue = !assumeTrue;
+                }
+                if (assumeTrue && !(type.flags & 65536 /* Union */)) {
+                    // We narrow a non-union type to an exact primitive type if the non-union type
+                    // is a supertype of that primitive type. For example, type 'any' can be narrowed
+                    // to one of the primitive types.
+                    var targetType = typeofTypesByName.get(literal.text);
+                    if (targetType) {
+                        if (isTypeSubtypeOf(targetType, type)) {
+                            return targetType;
+                        }
+                        if (type.flags & 540672 /* TypeVariable */) {
+                            var constraint = getBaseConstraintOfType(type) || anyType;
+                            if (isTypeSubtypeOf(targetType, constraint)) {
+                                return getIntersectionType([type, targetType]);
+                            }
+                        }
+                    }
+                }
+                var facts = assumeTrue ?
+                    typeofEQFacts.get(literal.text) || 64 /* TypeofEQHostObject */ :
+                    typeofNEFacts.get(literal.text) || 8192 /* TypeofNEHostObject */;
+                return getTypeWithFacts(type, facts);
+            }
+            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
+                // We only narrow if all case expressions specify values with unit types
+                var switchTypes = getSwitchClauseTypes(switchStatement);
+                if (!switchTypes.length) {
+                    return type;
+                }
+                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
+                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType);
+                var discriminantType = getUnionType(clauseTypes);
+                var caseType = discriminantType.flags & 8192 /* Never */ ? neverType :
+                    replacePrimitivesWithLiterals(filterType(type, function (t) { return isTypeComparableTo(discriminantType, t); }), discriminantType);
+                if (!hasDefaultClause) {
+                    return caseType;
+                }
+                var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); });
+                return caseType.flags & 8192 /* Never */ ? defaultType : getUnionType([caseType, defaultType]);
+            }
+            function narrowTypeByInstanceof(type, expr, assumeTrue) {
+                var left = getReferenceCandidate(expr.left);
+                if (!isMatchingReference(reference, left)) {
+                    // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
+                    // narrowed type of 'y' to its declared type.
+                    if (containsMatchingReference(reference, left)) {
+                        return declaredType;
+                    }
+                    return type;
+                }
+                // Check that right operand is a function type with a prototype property
+                var rightType = getTypeOfExpression(expr.right);
+                if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
+                    return type;
+                }
+                var targetType;
+                var prototypeProperty = getPropertyOfType(rightType, "prototype");
+                if (prototypeProperty) {
+                    // Target type is type of the prototype property
+                    var prototypePropertyType = getTypeOfSymbol(prototypeProperty);
+                    if (!isTypeAny(prototypePropertyType)) {
+                        targetType = prototypePropertyType;
+                    }
+                }
+                // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
+                if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
+                    return type;
+                }
+                if (!targetType) {
+                    // Target type is type of construct signature
+                    var constructSignatures = void 0;
+                    if (getObjectFlags(rightType) & 2 /* Interface */) {
+                        constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
+                    }
+                    else if (getObjectFlags(rightType) & 16 /* Anonymous */) {
+                        constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
+                    }
+                    if (constructSignatures && constructSignatures.length) {
+                        targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
+                    }
+                }
+                if (targetType) {
+                    return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf);
+                }
+                return type;
+            }
+            function getNarrowedType(type, candidate, assumeTrue, isRelated) {
+                if (!assumeTrue) {
+                    return filterType(type, function (t) { return !isRelated(t, candidate); });
+                }
+                // If the current type is a union type, remove all constituents that couldn't be instances of
+                // the candidate type. If one or more constituents remain, return a union of those.
+                if (type.flags & 65536 /* Union */) {
+                    var assignableType = filterType(type, function (t) { return isRelated(t, candidate); });
+                    if (!(assignableType.flags & 8192 /* Never */)) {
+                        return assignableType;
+                    }
+                }
+                // If the candidate type is a subtype of the target type, narrow to the candidate type.
+                // Otherwise, if the target type is assignable to the candidate type, keep the target type.
+                // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate
+                // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the
+                // two types.
+                return isTypeSubtypeOf(candidate, type) ? candidate :
+                    isTypeAssignableTo(type, candidate) ? type :
+                        isTypeAssignableTo(candidate, type) ? candidate :
+                            getIntersectionType([type, candidate]);
+            }
+            function narrowTypeByTypePredicate(type, callExpression, assumeTrue) {
+                if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) {
+                    return type;
+                }
+                var signature = getResolvedSignature(callExpression);
+                var predicate = signature.typePredicate;
+                if (!predicate) {
+                    return type;
+                }
+                // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
+                if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) {
+                    return type;
+                }
+                if (ts.isIdentifierTypePredicate(predicate)) {
+                    var predicateArgument = callExpression.arguments[predicate.parameterIndex - (signature.thisParameter ? 1 : 0)];
+                    if (predicateArgument) {
+                        if (isMatchingReference(reference, predicateArgument)) {
+                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
+                        }
+                        if (containsMatchingReference(reference, predicateArgument)) {
+                            return declaredType;
+                        }
+                    }
+                }
+                else {
+                    var invokedExpression = ts.skipParentheses(callExpression.expression);
+                    if (invokedExpression.kind === 180 /* ElementAccessExpression */ || invokedExpression.kind === 179 /* PropertyAccessExpression */) {
+                        var accessExpression = invokedExpression;
+                        var possibleReference = ts.skipParentheses(accessExpression.expression);
+                        if (isMatchingReference(reference, possibleReference)) {
+                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
+                        }
+                        if (containsMatchingReference(reference, possibleReference)) {
+                            return declaredType;
+                        }
+                    }
+                }
+                return type;
+            }
+            // Narrow the given type based on the given expression having the assumed boolean value. The returned type
+            // will be a subtype or the same type as the argument.
+            function narrowType(type, expr, assumeTrue) {
+                switch (expr.kind) {
+                    case 71 /* Identifier */:
+                    case 99 /* ThisKeyword */:
+                    case 97 /* SuperKeyword */:
+                    case 179 /* PropertyAccessExpression */:
+                        return narrowTypeByTruthiness(type, expr, assumeTrue);
+                    case 181 /* CallExpression */:
+                        return narrowTypeByTypePredicate(type, expr, assumeTrue);
+                    case 185 /* ParenthesizedExpression */:
+                        return narrowType(type, expr.expression, assumeTrue);
+                    case 194 /* BinaryExpression */:
+                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
+                    case 192 /* PrefixUnaryExpression */:
+                        if (expr.operator === 51 /* ExclamationToken */) {
+                            return narrowType(type, expr.operand, !assumeTrue);
+                        }
+                        break;
+                }
+                return type;
+            }
+        }
+        function getTypeOfSymbolAtLocation(symbol, location) {
+            symbol = symbol.exportSymbol || symbol;
+            // If we have an identifier or a property access at the given location, if the location is
+            // an dotted name expression, and if the location is not an assignment target, obtain the type
+            // of the expression (which will reflect control flow analysis). If the expression indeed
+            // resolved to the given symbol, return the narrowed type.
+            if (location.kind === 71 /* Identifier */) {
+                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
+                    location = location.parent;
+                }
+                if (ts.isPartOfExpression(location) && !ts.isAssignmentTarget(location)) {
+                    var type = getTypeOfExpression(location);
+                    if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
+                        return type;
+                    }
+                }
+            }
+            // The location isn't a reference to the given symbol, meaning we're being asked
+            // a hypothetical question of what type the symbol would have if there was a reference
+            // to it at the given location. Since we have no control flow information for the
+            // hypothetical reference (control flow information is created and attached by the
+            // binder), we simply return the declared type of the symbol.
+            return getTypeOfSymbol(symbol);
+        }
+        function getControlFlowContainer(node) {
+            return ts.findAncestor(node.parent, function (node) {
+                return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) ||
+                    node.kind === 234 /* ModuleBlock */ ||
+                    node.kind === 265 /* SourceFile */ ||
+                    node.kind === 149 /* PropertyDeclaration */;
+            });
+        }
+        // Check if a parameter is assigned anywhere within its declaring function.
+        function isParameterAssigned(symbol) {
+            var func = ts.getRootDeclaration(symbol.valueDeclaration).parent;
+            var links = getNodeLinks(func);
+            if (!(links.flags & 4194304 /* AssignmentsMarked */)) {
+                links.flags |= 4194304 /* AssignmentsMarked */;
+                if (!hasParentWithAssignmentsMarked(func)) {
+                    markParameterAssignments(func);
+                }
+            }
+            return symbol.isAssigned || false;
+        }
+        function hasParentWithAssignmentsMarked(node) {
+            return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 4194304 /* AssignmentsMarked */); });
+        }
+        function markParameterAssignments(node) {
+            if (node.kind === 71 /* Identifier */) {
+                if (ts.isAssignmentTarget(node)) {
+                    var symbol = getResolvedSymbol(node);
+                    if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 146 /* Parameter */) {
+                        symbol.isAssigned = true;
+                    }
+                }
+            }
+            else {
+                ts.forEachChild(node, markParameterAssignments);
+            }
+        }
+        function isConstVariable(symbol) {
+            return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
+        }
+        /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
+        function removeOptionalityFromDeclaredType(declaredType, declaration) {
+            var annotationIncludesUndefined = strictNullChecks &&
+                declaration.kind === 146 /* Parameter */ &&
+                declaration.initializer &&
+                getFalsyFlags(declaredType) & 2048 /* Undefined */ &&
+                !(getFalsyFlags(checkExpression(declaration.initializer)) & 2048 /* Undefined */);
+            return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 131072 /* NEUndefined */) : declaredType;
+        }
+        function isApparentTypePosition(node) {
+            var parent = node.parent;
+            return parent.kind === 179 /* PropertyAccessExpression */ ||
+                parent.kind === 181 /* CallExpression */ && parent.expression === node ||
+                parent.kind === 180 /* ElementAccessExpression */ && parent.expression === node;
+        }
+        function typeHasNullableConstraint(type) {
+            return type.flags & 540672 /* TypeVariable */ && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, 6144 /* Nullable */);
+        }
+        function getDeclaredOrApparentType(symbol, node) {
+            // When a node is the left hand expression of a property access, element access, or call expression,
+            // and the type of the node includes type variables with constraints that are nullable, we fetch the
+            // apparent type of the node *before* performing control flow analysis such that narrowings apply to
+            // the constraint type.
+            var type = getTypeOfSymbol(symbol);
+            if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) {
+                return mapType(getWidenedType(type), getApparentType);
+            }
+            return type;
+        }
+        function checkIdentifier(node) {
+            var symbol = getResolvedSymbol(node);
+            if (symbol === unknownSymbol) {
+                return unknownType;
+            }
+            // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
+            // Although in down-level emit of arrow function, we emit it using function expression which means that
+            // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
+            // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
+            // To avoid that we will give an error to users if they use arguments objects in arrow function so that they
+            // can explicitly bound arguments objects
+            if (symbol === argumentsSymbol) {
+                var container = ts.getContainingFunction(node);
+                if (languageVersion < 2 /* ES2015 */) {
+                    if (container.kind === 187 /* ArrowFunction */) {
+                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
+                    }
+                    else if (ts.hasModifier(container, 256 /* Async */)) {
+                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method);
+                    }
+                }
+                getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
+                return getTypeOfSymbol(symbol);
+            }
+            // We should only mark aliases as referenced if there isn't a local value declaration
+            // for the symbol.
+            if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */) && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
+                markAliasSymbolAsReferenced(symbol);
+            }
+            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
+            var declaration = localOrExportSymbol.valueDeclaration;
+            if (localOrExportSymbol.flags & 32 /* Class */) {
+                // Due to the emit for class decorators, any reference to the class from inside of the class body
+                // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
+                // behavior of class names in ES6.
+                if (declaration.kind === 229 /* ClassDeclaration */
+                    && ts.nodeIsDecorated(declaration)) {
+                    var container = ts.getContainingClass(node);
+                    while (container !== undefined) {
+                        if (container === declaration && container.name !== node) {
+                            getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */;
+                            getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */;
+                            break;
+                        }
+                        container = ts.getContainingClass(container);
+                    }
+                }
+                else if (declaration.kind === 199 /* ClassExpression */) {
+                    // When we emit a class expression with static members that contain a reference
+                    // to the constructor in the initializer, we will need to substitute that
+                    // binding with an alias as the class name is not in scope.
+                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
+                    while (container !== undefined) {
+                        if (container.parent === declaration) {
+                            if (container.kind === 149 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) {
+                                getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */;
+                                getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */;
+                            }
+                            break;
+                        }
+                        container = ts.getThisContainer(container, /*includeArrowFunctions*/ false);
+                    }
+                }
+            }
+            checkCollisionWithCapturedSuperVariable(node, node);
+            checkCollisionWithCapturedThisVariable(node, node);
+            checkCollisionWithCapturedNewTargetVariable(node, node);
+            checkNestedBlockScopedBinding(node, symbol);
+            var type = getDeclaredOrApparentType(localOrExportSymbol, node);
+            var assignmentKind = ts.getAssignmentTargetKind(node);
+            if (assignmentKind) {
+                if (!(localOrExportSymbol.flags & 3 /* Variable */)) {
+                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol));
+                    return unknownType;
+                }
+                if (isReadonlySymbol(localOrExportSymbol)) {
+                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(symbol));
+                    return unknownType;
+                }
+            }
+            var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */;
+            // We only narrow variables and parameters occurring in a non-assignment position. For all other
+            // entities we simply return the declared type.
+            if (localOrExportSymbol.flags & 3 /* Variable */) {
+                if (assignmentKind === 1 /* Definite */) {
+                    return type;
+                }
+            }
+            else if (isAlias) {
+                declaration = ts.find(symbol.declarations, isSomeImportDeclaration);
+            }
+            else {
+                return type;
+            }
+            if (!declaration) {
+                return type;
+            }
+            // The declaration container is the innermost function that encloses the declaration of the variable
+            // or parameter. The flow container is the innermost function starting with which we analyze the control
+            // flow graph to determine the control flow based type.
+            var isParameter = ts.getRootDeclaration(declaration).kind === 146 /* Parameter */;
+            var declarationContainer = getControlFlowContainer(declaration);
+            var flowContainer = getControlFlowContainer(node);
+            var isOuterVariable = flowContainer !== declarationContainer;
+            // When the control flow originates in a function expression or arrow function and we are referencing
+            // a const variable or parameter from an outer function, we extend the origin of the control flow
+            // analysis to include the immediately enclosing function.
+            while (flowContainer !== declarationContainer && (flowContainer.kind === 186 /* FunctionExpression */ ||
+                flowContainer.kind === 187 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
+                (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
+                flowContainer = getControlFlowContainer(flowContainer);
+            }
+            // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
+            // the entire control flow graph from the variable's declaration (i.e. when the flow container and
+            // declaration container are the same).
+            var assumeInitialized = isParameter || isAlias || isOuterVariable ||
+                type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & 1 /* Any */) !== 0 || isInTypeQuery(node) || node.parent.kind === 246 /* ExportSpecifier */) ||
+                node.parent.kind === 203 /* NonNullExpression */ ||
+                ts.isInAmbientContext(declaration);
+            var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, ts.getRootDeclaration(declaration)) : type) :
+                type === autoType || type === autoArrayType ? undefinedType :
+                    getNullableType(type, 2048 /* Undefined */);
+            var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
+            // A variable is considered uninitialized when it is possible to analyze the entire control flow graph
+            // from declaration to use, and when the variable's declared type doesn't include undefined but the
+            // control flow based type does include undefined.
+            if (type === autoType || type === autoArrayType) {
+                if (flowType === autoType || flowType === autoArrayType) {
+                    if (noImplicitAny) {
+                        error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
+                        error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
+                    }
+                    return convertAutoToAny(flowType);
+                }
+            }
+            else if (!assumeInitialized && !(getFalsyFlags(type) & 2048 /* Undefined */) && getFalsyFlags(flowType) & 2048 /* Undefined */) {
+                error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
+                // Return the declared type to reduce follow-on errors
+                return type;
+            }
+            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
+        }
+        function isInsideFunction(node, threshold) {
+            return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); });
+        }
+        function checkNestedBlockScopedBinding(node, symbol) {
+            if (languageVersion >= 2 /* ES2015 */ ||
+                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
+                symbol.valueDeclaration.parent.kind === 260 /* CatchClause */) {
+                return;
+            }
+            // 1. walk from the use site up to the declaration and check
+            // if there is anything function like between declaration and use-site (is binding/class is captured in function).
+            // 2. walk from the declaration up to the boundary of lexical environment and check
+            // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
+            var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
+            var usedInFunction = isInsideFunction(node.parent, container);
+            var current = container;
+            var containedInIterationStatement = false;
+            while (current && !ts.nodeStartsNewLexicalEnvironment(current)) {
+                if (ts.isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
+                    containedInIterationStatement = true;
+                    break;
+                }
+                current = current.parent;
+            }
+            if (containedInIterationStatement) {
+                if (usedInFunction) {
+                    // mark iteration statement as containing block-scoped binding captured in some function
+                    getNodeLinks(current).flags |= 65536 /* LoopWithCapturedBlockScopedBinding */;
+                }
+                // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
+                // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back.
+                if (container.kind === 214 /* ForStatement */ &&
+                    ts.getAncestor(symbol.valueDeclaration, 227 /* VariableDeclarationList */).parent === container &&
+                    isAssignedInBodyOfForStatement(node, container)) {
+                    getNodeLinks(symbol.valueDeclaration).flags |= 2097152 /* NeedsLoopOutParameter */;
+                }
+                // set 'declared inside loop' bit on the block-scoped binding
+                getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* BlockScopedBindingInLoop */;
+            }
+            if (usedInFunction) {
+                getNodeLinks(symbol.valueDeclaration).flags |= 131072 /* CapturedBlockScopedBinding */;
+            }
+        }
+        function isAssignedInBodyOfForStatement(node, container) {
+            // skip parenthesized nodes
+            var current = node;
+            while (current.parent.kind === 185 /* ParenthesizedExpression */) {
+                current = current.parent;
+            }
+            // check if node is used as LHS in some assignment expression
+            var isAssigned = false;
+            if (ts.isAssignmentTarget(current)) {
+                isAssigned = true;
+            }
+            else if ((current.parent.kind === 192 /* PrefixUnaryExpression */ || current.parent.kind === 193 /* PostfixUnaryExpression */)) {
+                var expr = current.parent;
+                isAssigned = expr.operator === 43 /* PlusPlusToken */ || expr.operator === 44 /* MinusMinusToken */;
+            }
+            if (!isAssigned) {
+                return false;
+            }
+            // at this point we know that node is the target of assignment
+            // now check that modification happens inside the statement part of the ForStatement
+            return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; });
+        }
+        function captureLexicalThis(node, container) {
+            getNodeLinks(node).flags |= 2 /* LexicalThis */;
+            if (container.kind === 149 /* PropertyDeclaration */ || container.kind === 152 /* Constructor */) {
+                var classNode = container.parent;
+                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
+            }
+            else {
+                getNodeLinks(container).flags |= 4 /* CaptureThis */;
+            }
+        }
+        function findFirstSuperCall(n) {
+            if (ts.isSuperCall(n)) {
+                return n;
+            }
+            else if (ts.isFunctionLike(n)) {
+                return undefined;
+            }
+            return ts.forEachChild(n, findFirstSuperCall);
+        }
+        /**
+         * Return a cached result if super-statement is already found.
+         * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
+         *
+         * @param constructor constructor-function to look for super statement
+         */
+        function getSuperCallInConstructor(constructor) {
+            var links = getNodeLinks(constructor);
+            // Only trying to find super-call if we haven't yet tried to find one.  Once we try, we will record the result
+            if (links.hasSuperCall === undefined) {
+                links.superCall = findFirstSuperCall(constructor.body);
+                links.hasSuperCall = links.superCall ? true : false;
+            }
+            return links.superCall;
+        }
+        /**
+         * Check if the given class-declaration extends null then return true.
+         * Otherwise, return false
+         * @param classDecl a class declaration to check if it extends null
+         */
+        function classDeclarationExtendsNull(classDecl) {
+            var classSymbol = getSymbolOfNode(classDecl);
+            var classInstanceType = getDeclaredTypeOfSymbol(classSymbol);
+            var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
+            return baseConstructorType === nullWideningType;
+        }
+        function checkThisBeforeSuper(node, container, diagnosticMessage) {
+            var containingClassDecl = container.parent;
+            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(containingClassDecl);
+            // If a containing class does not have extends clause or the class extends null
+            // skip checking whether super statement is called before "this" accessing.
+            if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
+                var superCall = getSuperCallInConstructor(container);
+                // We should give an error in the following cases:
+                //      - No super-call
+                //      - "this" is accessing before super-call.
+                //          i.e super(this)
+                //              this.x; super();
+                // We want to make sure that super-call is done before accessing "this" so that
+                // "this" is not accessed as a parameter of the super-call.
+                if (!superCall || superCall.end > node.pos) {
+                    // In ES6, super inside constructor of class-declaration has to precede "this" accessing
+                    error(node, diagnosticMessage);
+                }
+            }
+        }
+        function checkThisExpression(node) {
+            // Stop at the first arrow function so that we can
+            // tell whether 'this' needs to be captured.
+            var container = ts.getThisContainer(node, /* includeArrowFunctions */ true);
+            var needToCaptureLexicalThis = false;
+            if (container.kind === 152 /* Constructor */) {
+                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
+            }
+            // Now skip arrow functions to get the "real" owner of 'this'.
+            if (container.kind === 187 /* ArrowFunction */) {
+                container = ts.getThisContainer(container, /* includeArrowFunctions */ false);
+                // When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code
+                needToCaptureLexicalThis = (languageVersion < 2 /* ES2015 */);
+            }
+            switch (container.kind) {
+                case 233 /* ModuleDeclaration */:
+                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
+                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
+                    break;
+                case 232 /* EnumDeclaration */:
+                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
+                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
+                    break;
+                case 152 /* Constructor */:
+                    if (isInConstructorArgumentInitializer(node, container)) {
+                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
+                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
+                    }
+                    break;
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    if (ts.hasModifier(container, 32 /* Static */)) {
+                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
+                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
+                    }
+                    break;
+                case 144 /* ComputedPropertyName */:
+                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
+                    break;
+            }
+            if (needToCaptureLexicalThis) {
+                captureLexicalThis(node, container);
+            }
+            if (ts.isFunctionLike(container) &&
+                (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) {
+                // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
+                // If this is a function in a JS file, it might be a class method. Check if it's the RHS
+                // of a x.prototype.y = function [name]() { .... }
+                if (container.kind === 186 /* FunctionExpression */ &&
+                    container.parent.kind === 194 /* BinaryExpression */ &&
+                    ts.getSpecialPropertyAssignmentKind(container.parent) === 3 /* PrototypeProperty */) {
+                    // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
+                    var className = container.parent // x.prototype.y = f
+                        .left // x.prototype.y
+                        .expression // x.prototype
+                        .expression; // x
+                    var classSymbol = checkExpression(className).symbol;
+                    if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) {
+                        return getInferredClassType(classSymbol);
+                    }
+                }
+                var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
+                if (thisType) {
+                    return thisType;
+                }
+            }
+            if (ts.isClassLike(container.parent)) {
+                var symbol = getSymbolOfNode(container.parent);
+                var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
+                return getFlowTypeOfReference(node, type);
+            }
+            if (ts.isInJavaScriptFile(node)) {
+                var type = getTypeForThisExpressionFromJSDoc(container);
+                if (type && type !== unknownType) {
+                    return type;
+                }
+            }
+            if (noImplicitThis) {
+                // With noImplicitThis, functions may not reference 'this' if it has type 'any'
+                error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
+            }
+            return anyType;
+        }
+        function getTypeForThisExpressionFromJSDoc(node) {
+            var jsdocType = ts.getJSDocType(node);
+            if (jsdocType && jsdocType.kind === 273 /* JSDocFunctionType */) {
+                var jsDocFunctionType = jsdocType;
+                if (jsDocFunctionType.parameters.length > 0 &&
+                    jsDocFunctionType.parameters[0].name &&
+                    jsDocFunctionType.parameters[0].name.escapedText === "this") {
+                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
+                }
+            }
+        }
+        function isInConstructorArgumentInitializer(node, constructorDecl) {
+            return !!ts.findAncestor(node, function (n) { return n === constructorDecl ? "quit" : n.kind === 146 /* Parameter */; });
+        }
+        function checkSuperExpression(node) {
+            var isCallExpression = node.parent.kind === 181 /* CallExpression */ && node.parent.expression === node;
+            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
+            var needToCaptureLexicalThis = false;
+            // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting
+            if (!isCallExpression) {
+                while (container && container.kind === 187 /* ArrowFunction */) {
+                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
+                    needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */;
+                }
+            }
+            var canUseSuperExpression = isLegalUsageOfSuperExpression(container);
+            var nodeCheckFlag = 0;
+            if (!canUseSuperExpression) {
+                // issue more specific error if super is used in computed property name
+                // class A { foo() { return "1" }}
+                // class B {
+                //     [super.foo()]() {}
+                // }
+                var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 144 /* ComputedPropertyName */; });
+                if (current && current.kind === 144 /* ComputedPropertyName */) {
+                    error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
+                }
+                else if (isCallExpression) {
+                    error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
+                }
+                else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */)) {
+                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions);
+                }
+                else {
+                    error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
+                }
+                return unknownType;
+            }
+            if (!isCallExpression && container.kind === 152 /* Constructor */) {
+                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
+            }
+            if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) {
+                nodeCheckFlag = 512 /* SuperStatic */;
+            }
+            else {
+                nodeCheckFlag = 256 /* SuperInstance */;
+            }
+            getNodeLinks(node).flags |= nodeCheckFlag;
+            // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference.
+            // This is due to the fact that we emit the body of an async function inside of a generator function. As generator
+            // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper
+            // uses an arrow function, which is permitted to reference `super`.
+            //
+            // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property
+            // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value
+            // of a property or indexed access, either as part of an assignment expression or destructuring assignment.
+            //
+            // The simplest case is reading a value, in which case we will emit something like the following:
+            //
+            //  // ts
+            //  ...
+            //  async asyncMethod() {
+            //    let x = await super.asyncMethod();
+            //    return x;
+            //  }
+            //  ...
+            //
+            //  // js
+            //  ...
+            //  asyncMethod() {
+            //      const _super = name => super[name];
+            //      return __awaiter(this, arguments, Promise, function *() {
+            //          let x = yield _super("asyncMethod").call(this);
+            //          return x;
+            //      });
+            //  }
+            //  ...
+            //
+            // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
+            // are legal in ES6, but also likely less frequent, we emit the same more complex helper for both scenarios:
+            //
+            //  // ts
+            //  ...
+            //  async asyncMethod(ar: Promise<any[]>) {
+            //      [super.a, super.b] = await ar;
+            //  }
+            //  ...
+            //
+            //  // js
+            //  ...
+            //  asyncMethod(ar) {
+            //      const _super = (function (geti, seti) {
+            //          const cache = Object.create(null);
+            //          return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
+            //      })(name => super[name], (name, value) => super[name] = value);
+            //      return __awaiter(this, arguments, Promise, function *() {
+            //          [_super("a").value, _super("b").value] = yield ar;
+            //      });
+            //  }
+            //  ...
+            //
+            // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set.
+            // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment
+            // while a property access can.
+            if (container.kind === 151 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) {
+                if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) {
+                    getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */;
+                }
+                else {
+                    getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */;
+                }
+            }
+            if (needToCaptureLexicalThis) {
+                // call expressions are allowed only in constructors so they should always capture correct 'this'
+                // super property access expressions can also appear in arrow functions -
+                // in this case they should also use correct lexical this
+                captureLexicalThis(node.parent, container);
+            }
+            if (container.parent.kind === 178 /* ObjectLiteralExpression */) {
+                if (languageVersion < 2 /* ES2015 */) {
+                    error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
+                    return unknownType;
+                }
+                else {
+                    // for object literal assume that type of 'super' is 'any'
+                    return anyType;
+                }
+            }
+            // at this point the only legal case for parent is ClassLikeDeclaration
+            var classLikeDeclaration = container.parent;
+            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
+            var baseClassType = classType && getBaseTypes(classType)[0];
+            if (!baseClassType) {
+                if (!ts.getClassExtendsHeritageClauseElement(classLikeDeclaration)) {
+                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
+                }
+                return unknownType;
+            }
+            if (container.kind === 152 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
+                // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
+                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
+                return unknownType;
+            }
+            return nodeCheckFlag === 512 /* SuperStatic */
+                ? getBaseConstructorTypeOfClass(classType)
+                : getTypeWithThisArgument(baseClassType, classType.thisType);
+            function isLegalUsageOfSuperExpression(container) {
+                if (!container) {
+                    return false;
+                }
+                if (isCallExpression) {
+                    // TS 1.0 SPEC (April 2014): 4.8.1
+                    // Super calls are only permitted in constructors of derived classes
+                    return container.kind === 152 /* Constructor */;
+                }
+                else {
+                    // TS 1.0 SPEC (April 2014)
+                    // 'super' property access is allowed
+                    // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
+                    // - In a static member function or static member accessor
+                    // topmost container must be something that is directly nested in the class declaration\object literal expression
+                    if (ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */) {
+                        if (ts.hasModifier(container, 32 /* Static */)) {
+                            return container.kind === 151 /* MethodDeclaration */ ||
+                                container.kind === 150 /* MethodSignature */ ||
+                                container.kind === 153 /* GetAccessor */ ||
+                                container.kind === 154 /* SetAccessor */;
+                        }
+                        else {
+                            return container.kind === 151 /* MethodDeclaration */ ||
+                                container.kind === 150 /* MethodSignature */ ||
+                                container.kind === 153 /* GetAccessor */ ||
+                                container.kind === 154 /* SetAccessor */ ||
+                                container.kind === 149 /* PropertyDeclaration */ ||
+                                container.kind === 148 /* PropertySignature */ ||
+                                container.kind === 152 /* Constructor */;
+                        }
+                    }
+                }
+                return false;
+            }
+        }
+        function getContainingObjectLiteral(func) {
+            return (func.kind === 151 /* MethodDeclaration */ ||
+                func.kind === 153 /* GetAccessor */ ||
+                func.kind === 154 /* SetAccessor */) && func.parent.kind === 178 /* ObjectLiteralExpression */ ? func.parent :
+                func.kind === 186 /* FunctionExpression */ && func.parent.kind === 261 /* PropertyAssignment */ ? func.parent.parent :
+                    undefined;
+        }
+        function getThisTypeArgument(type) {
+            return getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? type.typeArguments[0] : undefined;
+        }
+        function getThisTypeFromContextualType(type) {
+            return mapType(type, function (t) {
+                return t.flags & 131072 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t);
+            });
+        }
+        function getContextualThisParameterType(func) {
+            if (func.kind === 187 /* ArrowFunction */) {
+                return undefined;
+            }
+            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
+                var contextualSignature = getContextualSignature(func);
+                if (contextualSignature) {
+                    var thisParameter = contextualSignature.thisParameter;
+                    if (thisParameter) {
+                        return getTypeOfSymbol(thisParameter);
+                    }
+                }
+            }
+            var inJs = ts.isInJavaScriptFile(func);
+            if (noImplicitThis || inJs) {
+                var containingLiteral = getContainingObjectLiteral(func);
+                if (containingLiteral) {
+                    // We have an object literal method. Check if the containing object literal has a contextual type
+                    // that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
+                    // any directly enclosing object literals.
+                    var contextualType = getApparentTypeOfContextualType(containingLiteral);
+                    var literal = containingLiteral;
+                    var type = contextualType;
+                    while (type) {
+                        var thisType = getThisTypeFromContextualType(type);
+                        if (thisType) {
+                            return instantiateType(thisType, getContextualMapper(containingLiteral));
+                        }
+                        if (literal.parent.kind !== 261 /* PropertyAssignment */) {
+                            break;
+                        }
+                        literal = literal.parent.parent;
+                        type = getApparentTypeOfContextualType(literal);
+                    }
+                    // There was no contextual ThisType<T> for the containing object literal, so the contextual type
+                    // for 'this' is the non-null form of the contextual type for the containing object literal or
+                    // the type of the object literal itself.
+                    return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral);
+                }
+                // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
+                // contextual type for 'this' is 'obj'.
+                var parent = func.parent;
+                if (parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */) {
+                    var target = parent.left;
+                    if (target.kind === 179 /* PropertyAccessExpression */ || target.kind === 180 /* ElementAccessExpression */) {
+                        var expression = target.expression;
+                        // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }`
+                        if (inJs && ts.isIdentifier(expression)) {
+                            var sourceFile = ts.getSourceFileOfNode(parent);
+                            if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) {
+                                return undefined;
+                            }
+                        }
+                        return checkExpressionCached(expression);
+                    }
+                }
+            }
+            return undefined;
+        }
+        // Return contextual type of parameter or undefined if no contextual type is available
+        function getContextuallyTypedParameterType(parameter) {
+            var func = parameter.parent;
+            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
+                var iife = ts.getImmediatelyInvokedFunctionExpression(func);
+                if (iife && iife.arguments) {
+                    var indexOfParameter = ts.indexOf(func.parameters, parameter);
+                    if (parameter.dotDotDotToken) {
+                        var restTypes = [];
+                        for (var i = indexOfParameter; i < iife.arguments.length; i++) {
+                            restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
+                        }
+                        return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
+                    }
+                    var links = getNodeLinks(iife);
+                    var cached = links.resolvedSignature;
+                    links.resolvedSignature = anySignature;
+                    var type = indexOfParameter < iife.arguments.length ?
+                        getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
+                        parameter.initializer ? undefined : undefinedWideningType;
+                    links.resolvedSignature = cached;
+                    return type;
+                }
+                var contextualSignature = getContextualSignature(func);
+                if (contextualSignature) {
+                    var funcHasRestParameters = ts.hasRestParameter(func);
+                    var len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
+                    var indexOfParameter = ts.indexOf(func.parameters, parameter);
+                    if (ts.getThisParameter(func) !== undefined && !contextualSignature.thisParameter) {
+                        ts.Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`.
+                        indexOfParameter -= 1;
+                    }
+                    if (indexOfParameter < len) {
+                        return getTypeAtPosition(contextualSignature, indexOfParameter);
+                    }
+                    // If last parameter is contextually rest parameter get its type
+                    if (funcHasRestParameters &&
+                        indexOfParameter === (func.parameters.length - 1) &&
+                        isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
+                        return getTypeOfSymbol(ts.lastOrUndefined(contextualSignature.parameters));
+                    }
+                }
+            }
+            return undefined;
+        }
+        // In a variable, parameter or property declaration with a type annotation,
+        //   the contextual type of an initializer expression is the type of the variable, parameter or property.
+        // Otherwise, in a parameter declaration of a contextually typed function expression,
+        //   the contextual type of an initializer expression is the contextual type of the parameter.
+        // Otherwise, in a variable or parameter declaration with a binding pattern name,
+        //   the contextual type of an initializer expression is the type implied by the binding pattern.
+        // Otherwise, in a binding pattern inside a variable or parameter declaration,
+        //   the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
+        function getContextualTypeForInitializerExpression(node) {
+            var declaration = node.parent;
+            if (node === declaration.initializer) {
+                var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
+                if (typeNode) {
+                    return getTypeFromTypeNode(typeNode);
+                }
+                if (declaration.kind === 146 /* Parameter */) {
+                    var type = getContextuallyTypedParameterType(declaration);
+                    if (type) {
+                        return type;
+                    }
+                }
+                if (ts.isBindingPattern(declaration.name)) {
+                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
+                }
+                if (ts.isBindingPattern(declaration.parent)) {
+                    var parentDeclaration = declaration.parent.parent;
+                    var name = declaration.propertyName || declaration.name;
+                    if (parentDeclaration.kind !== 176 /* BindingElement */) {
+                        var parentTypeNode = ts.getEffectiveTypeAnnotationNode(parentDeclaration);
+                        if (parentTypeNode && !ts.isBindingPattern(name)) {
+                            var text = ts.getTextOfPropertyName(name);
+                            if (text) {
+                                return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text);
+                            }
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        function getContextualTypeForReturnExpression(node) {
+            var func = ts.getContainingFunction(node);
+            if (func) {
+                var functionFlags = ts.getFunctionFlags(func);
+                if (functionFlags & 1 /* Generator */) {
+                    return undefined;
+                }
+                var contextualReturnType = getContextualReturnType(func);
+                return functionFlags & 2 /* Async */
+                    ? contextualReturnType && getAwaitedTypeOfPromise(contextualReturnType) // Async function
+                    : contextualReturnType; // Regular function
+            }
+            return undefined;
+        }
+        function getContextualTypeForYieldOperand(node) {
+            var func = ts.getContainingFunction(node);
+            if (func) {
+                var functionFlags = ts.getFunctionFlags(func);
+                var contextualReturnType = getContextualReturnType(func);
+                if (contextualReturnType) {
+                    return node.asteriskToken
+                        ? contextualReturnType
+                        : getIteratedTypeOfGenerator(contextualReturnType, (functionFlags & 2 /* Async */) !== 0);
+                }
+            }
+            return undefined;
+        }
+        function isInParameterInitializerBeforeContainingFunction(node) {
+            while (node.parent && !ts.isFunctionLike(node.parent)) {
+                if (node.parent.kind === 146 /* Parameter */ && node.parent.initializer === node) {
+                    return true;
+                }
+                node = node.parent;
+            }
+            return false;
+        }
+        function getContextualReturnType(functionDecl) {
+            // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
+            // corresponding set accessor has a type annotation, return statements in the function are contextually typed
+            if (functionDecl.kind === 152 /* Constructor */ ||
+                ts.getEffectiveReturnTypeNode(functionDecl) ||
+                isGetAccessorWithAnnotatedSetAccessor(functionDecl)) {
+                return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
+            }
+            // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
+            // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
+            var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
+                return getReturnTypeOfSignature(signature);
+            }
+            return undefined;
+        }
+        // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter.
+        function getContextualTypeForArgument(callTarget, arg) {
+            var args = getEffectiveCallArguments(callTarget);
+            var argIndex = ts.indexOf(args, arg);
+            if (argIndex >= 0) {
+                // If we're already in the process of resolving the given signature, don't resolve again as
+                // that could cause infinite recursion. Instead, return anySignature.
+                var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget);
+                return getTypeAtPosition(signature, argIndex);
+            }
+            return undefined;
+        }
+        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
+            if (template.parent.kind === 183 /* TaggedTemplateExpression */) {
+                return getContextualTypeForArgument(template.parent, substitutionExpression);
+            }
+            return undefined;
+        }
+        function getContextualTypeForBinaryOperand(node) {
+            var binaryExpression = node.parent;
+            var operator = binaryExpression.operatorToken.kind;
+            if (ts.isAssignmentOperator(operator)) {
+                if (node === binaryExpression.right) {
+                    // Don't do this for special property assignments to avoid circularity
+                    switch (ts.getSpecialPropertyAssignmentKind(binaryExpression)) {
+                        case 0 /* None */:
+                            break;
+                        case 5 /* Property */:
+                            // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
+                            // See `bindStaticPropertyAssignment` in `binder.ts`.
+                            if (!binaryExpression.left.symbol) {
+                                break;
+                            }
+                        // falls through
+                        case 1 /* ExportsProperty */:
+                        case 2 /* ModuleExports */:
+                        case 3 /* PrototypeProperty */:
+                        case 4 /* ThisProperty */:
+                            return undefined;
+                    }
+                    // In an assignment expression, the right operand is contextually typed by the type of the left operand.
+                    return getTypeOfExpression(binaryExpression.left);
+                }
+            }
+            else if (operator === 54 /* BarBarToken */) {
+                // When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
+                // expression has no contextual type, the right operand is contextually typed by the type of the left operand.
+                var type = getContextualType(binaryExpression);
+                if (!type && node === binaryExpression.right) {
+                    type = getTypeOfExpression(binaryExpression.left, /*cache*/ true);
+                }
+                return type;
+            }
+            else if (operator === 53 /* AmpersandAmpersandToken */ || operator === 26 /* CommaToken */) {
+                if (node === binaryExpression.right) {
+                    return getContextualType(binaryExpression);
+                }
+            }
+            return undefined;
+        }
+        function getTypeOfPropertyOfContextualType(type, name) {
+            return mapType(type, function (t) {
+                var prop = t.flags & 229376 /* StructuredType */ ? getPropertyOfType(t, name) : undefined;
+                return prop ? getTypeOfSymbol(prop) : undefined;
+            });
+        }
+        function getIndexTypeOfContextualType(type, kind) {
+            return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
+        }
+        // Return true if the given contextual type is a tuple-like type
+        function contextualTypeIsTupleLikeType(type) {
+            return !!(type.flags & 65536 /* Union */ ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
+        }
+        // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
+        // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
+        // exists. Otherwise, it is the type of the string index signature in T, if one exists.
+        function getContextualTypeForObjectLiteralMethod(node) {
+            ts.Debug.assert(ts.isObjectLiteralMethod(node));
+            if (isInsideWithStatementBody(node)) {
+                // We cannot answer semantic questions within a with block, do not proceed any further
+                return undefined;
+            }
+            return getContextualTypeForObjectLiteralElement(node);
+        }
+        function getContextualTypeForObjectLiteralElement(element) {
+            var objectLiteral = element.parent;
+            var type = getApparentTypeOfContextualType(objectLiteral);
+            if (type) {
+                if (!ts.hasDynamicName(element)) {
+                    // For a (non-symbol) computed property, there is no reason to look up the name
+                    // in the type. It will just be "__computed", which does not appear in any
+                    // SymbolTable.
+                    var symbolName_1 = getSymbolOfNode(element).escapedName;
+                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_1);
+                    if (propertyType) {
+                        return propertyType;
+                    }
+                }
+                return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) ||
+                    getIndexTypeOfContextualType(type, 0 /* String */);
+            }
+            return undefined;
+        }
+        // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
+        // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
+        // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
+        // type of T.
+        function getContextualTypeForElementExpression(arrayContextualType, index) {
+            return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index)
+                || getIndexTypeOfContextualType(arrayContextualType, 1 /* Number */)
+                || getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
+        }
+        // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
+        function getContextualTypeForConditionalOperand(node) {
+            var conditional = node.parent;
+            return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
+        }
+        function getContextualTypeForJsxExpression(node) {
+            // JSX expression can appear in two position : JSX Element's children or JSX attribute
+            var jsxAttributes = ts.isJsxAttributeLike(node.parent) ?
+                node.parent.parent :
+                node.parent.openingElement.attributes; // node.parent is JsxElement
+            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
+            // which is a type of the parameter of the signature we are trying out.
+            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
+            var attributesType = getContextualType(jsxAttributes);
+            if (!attributesType || isTypeAny(attributesType)) {
+                return undefined;
+            }
+            if (ts.isJsxAttribute(node.parent)) {
+                // JSX expression is in JSX attribute
+                return getTypeOfPropertyOfContextualType(attributesType, node.parent.name.escapedText);
+            }
+            else if (node.parent.kind === 249 /* JsxElement */) {
+                // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
+                var jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
+                return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : anyType;
+            }
+            else {
+                // JSX expression is in JSX spread attribute
+                return attributesType;
+            }
+        }
+        function getContextualTypeForJsxAttribute(attribute) {
+            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
+            // which is a type of the parameter of the signature we are trying out.
+            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
+            var attributesType = getContextualType(attribute.parent);
+            if (ts.isJsxAttribute(attribute)) {
+                if (!attributesType || isTypeAny(attributesType)) {
+                    return undefined;
+                }
+                return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
+            }
+            else {
+                return attributesType;
+            }
+        }
+        // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
+        // be "pushed" onto a node using the contextualType property.
+        function getApparentTypeOfContextualType(node) {
+            var type = getContextualType(node);
+            return type && getApparentType(type);
+        }
+        /**
+         * Woah! Do you really want to use this function?
+         *
+         * Unless you're trying to get the *non-apparent* type for a
+         * value-literal type or you're authoring relevant portions of this algorithm,
+         * you probably meant to use 'getApparentTypeOfContextualType'.
+         * Otherwise this may not be very useful.
+         *
+         * In cases where you *are* working on this function, you should understand
+         * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContextualType'.
+         *
+         *   - Use 'getContextualType' when you are simply going to propagate the result to the expression.
+         *   - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
+         *
+         * @param node the expression whose contextual type will be returned.
+         * @returns the contextual type of an expression.
+         */
+        function getContextualType(node) {
+            if (isInsideWithStatementBody(node)) {
+                // We cannot answer semantic questions within a with block, do not proceed any further
+                return undefined;
+            }
+            if (node.contextualType) {
+                return node.contextualType;
+            }
+            var parent = node.parent;
+            switch (parent.kind) {
+                case 226 /* VariableDeclaration */:
+                case 146 /* Parameter */:
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                case 176 /* BindingElement */:
+                    return getContextualTypeForInitializerExpression(node);
+                case 187 /* ArrowFunction */:
+                case 219 /* ReturnStatement */:
+                    return getContextualTypeForReturnExpression(node);
+                case 197 /* YieldExpression */:
+                    return getContextualTypeForYieldOperand(parent);
+                case 181 /* CallExpression */:
+                case 182 /* NewExpression */:
+                    return getContextualTypeForArgument(parent, node);
+                case 184 /* TypeAssertionExpression */:
+                case 202 /* AsExpression */:
+                    return getTypeFromTypeNode(parent.type);
+                case 194 /* BinaryExpression */:
+                    return getContextualTypeForBinaryOperand(node);
+                case 261 /* PropertyAssignment */:
+                case 262 /* ShorthandPropertyAssignment */:
+                    return getContextualTypeForObjectLiteralElement(parent);
+                case 263 /* SpreadAssignment */:
+                    return getApparentTypeOfContextualType(parent.parent);
+                case 177 /* ArrayLiteralExpression */: {
+                    var arrayLiteral = parent;
+                    var type = getApparentTypeOfContextualType(arrayLiteral);
+                    return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node));
+                }
+                case 195 /* ConditionalExpression */:
+                    return getContextualTypeForConditionalOperand(node);
+                case 205 /* TemplateSpan */:
+                    ts.Debug.assert(parent.parent.kind === 196 /* TemplateExpression */);
+                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
+                case 185 /* ParenthesizedExpression */: {
+                    // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
+                    var tag = ts.isInJavaScriptFile(parent) ? ts.getJSDocTypeTag(parent) : undefined;
+                    return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent);
+                }
+                case 256 /* JsxExpression */:
+                    return getContextualTypeForJsxExpression(parent);
+                case 253 /* JsxAttribute */:
+                case 255 /* JsxSpreadAttribute */:
+                    return getContextualTypeForJsxAttribute(parent);
+                case 251 /* JsxOpeningElement */:
+                case 250 /* JsxSelfClosingElement */:
+                    return getAttributesTypeFromJsxOpeningLikeElement(parent);
+            }
+            return undefined;
+        }
+        function getContextualMapper(node) {
+            node = ts.findAncestor(node, function (n) { return !!n.contextualMapper; });
+            return node ? node.contextualMapper : identityMapper;
+        }
+        // If the given type is an object or union type with a single signature, and if that signature has at
+        // least as many parameters as the given function, return the signature. Otherwise return undefined.
+        function getContextualCallSignature(type, node) {
+            var signatures = getSignaturesOfStructuredType(type, 0 /* Call */);
+            if (signatures.length === 1) {
+                var signature = signatures[0];
+                if (!isAritySmaller(signature, node)) {
+                    return signature;
+                }
+            }
+        }
+        /** If the contextual signature has fewer parameters than the function expression, do not use it */
+        function isAritySmaller(signature, target) {
+            var targetParameterCount = 0;
+            for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
+                var param = target.parameters[targetParameterCount];
+                if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
+                    break;
+                }
+            }
+            if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) {
+                targetParameterCount--;
+            }
+            var sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length;
+            return sourceLength < targetParameterCount;
+        }
+        function isFunctionExpressionOrArrowFunction(node) {
+            return node.kind === 186 /* FunctionExpression */ || node.kind === 187 /* ArrowFunction */;
+        }
+        function getContextualSignatureForFunctionLikeDeclaration(node) {
+            // Only function expressions, arrow functions, and object literal methods are contextually typed.
+            return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node)
+                ? getContextualSignature(node)
+                : undefined;
+        }
+        function getContextualTypeForFunctionLikeDeclaration(node) {
+            return ts.isObjectLiteralMethod(node) ?
+                getContextualTypeForObjectLiteralMethod(node) :
+                getApparentTypeOfContextualType(node);
+        }
+        // Return the contextual signature for a given expression node. A contextual type provides a
+        // contextual signature if it has a single call signature and if that call signature is non-generic.
+        // If the contextual type is a union type, get the signature from each type possible and if they are
+        // all identical ignoring their return type, the result is same signature but with return type as
+        // union type of return types from these signatures
+        function getContextualSignature(node) {
+            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
+            var type = getContextualTypeForFunctionLikeDeclaration(node);
+            if (!type) {
+                return undefined;
+            }
+            if (!(type.flags & 65536 /* Union */)) {
+                return getContextualCallSignature(type, node);
+            }
+            var signatureList;
+            var types = type.types;
+            for (var _i = 0, types_16 = types; _i < types_16.length; _i++) {
+                var current = types_16[_i];
+                var signature = getContextualCallSignature(current, node);
+                if (signature) {
+                    if (!signatureList) {
+                        // This signature will contribute to contextual union signature
+                        signatureList = [signature];
+                    }
+                    else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
+                        // Signatures aren't identical, do not use
+                        return undefined;
+                    }
+                    else {
+                        // Use this signature for contextual union signature
+                        signatureList.push(signature);
+                    }
+                }
+            }
+            // Result is union of signatures collected (return type is union of return types of this signature set)
+            var result;
+            if (signatureList) {
+                result = cloneSignature(signatureList[0]);
+                // Clear resolved return type we possibly got from cloneSignature
+                result.resolvedReturnType = undefined;
+                result.unionSignatures = signatureList;
+            }
+            return result;
+        }
+        function checkSpreadExpression(node, checkMode) {
+            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
+                checkExternalEmitHelpers(node, 1536 /* SpreadIncludes */);
+            }
+            var arrayOrIterableType = checkExpression(node.expression, checkMode);
+            return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
+        }
+        function hasDefaultValue(node) {
+            return (node.kind === 176 /* BindingElement */ && !!node.initializer) ||
+                (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */);
+        }
+        function checkArrayLiteral(node, checkMode) {
+            var elements = node.elements;
+            var hasSpreadElement = false;
+            var elementTypes = [];
+            var inDestructuringPattern = ts.isAssignmentTarget(node);
+            var contextualType = getApparentTypeOfContextualType(node);
+            for (var index = 0; index < elements.length; index++) {
+                var e = elements[index];
+                if (inDestructuringPattern && e.kind === 198 /* SpreadElement */) {
+                    // Given the following situation:
+                    //    var c: {};
+                    //    [...c] = ["", 0];
+                    //
+                    // c is represented in the tree as a spread element in an array literal.
+                    // But c really functions as a rest element, and its purpose is to provide
+                    // a contextual type for the right hand side of the assignment. Therefore,
+                    // instead of calling checkExpression on "...c", which will give an error
+                    // if c is not iterable/array-like, we need to act as if we are trying to
+                    // get the contextual element type from it. So we do something similar to
+                    // getContextualTypeForElementExpression, which will crucially not error
+                    // if there is no index type / iterated type.
+                    var restArrayType = checkExpression(e.expression, checkMode);
+                    var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) ||
+                        getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false);
+                    if (restElementType) {
+                        elementTypes.push(restElementType);
+                    }
+                }
+                else {
+                    var elementContextualType = getContextualTypeForElementExpression(contextualType, index);
+                    var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType);
+                    elementTypes.push(type);
+                }
+                hasSpreadElement = hasSpreadElement || e.kind === 198 /* SpreadElement */;
+            }
+            if (!hasSpreadElement) {
+                // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
+                // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
+                if (inDestructuringPattern && elementTypes.length) {
+                    var type = cloneTypeReference(createTupleType(elementTypes));
+                    type.pattern = node;
+                    return type;
+                }
+                var contextualType_1 = getApparentTypeOfContextualType(node);
+                if (contextualType_1 && contextualTypeIsTupleLikeType(contextualType_1)) {
+                    var pattern = contextualType_1.pattern;
+                    // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
+                    // tuple type with the corresponding binding or assignment element types to make the lengths equal.
+                    if (pattern && (pattern.kind === 175 /* ArrayBindingPattern */ || pattern.kind === 177 /* ArrayLiteralExpression */)) {
+                        var patternElements = pattern.elements;
+                        for (var i = elementTypes.length; i < patternElements.length; i++) {
+                            var patternElement = patternElements[i];
+                            if (hasDefaultValue(patternElement)) {
+                                elementTypes.push(contextualType_1.typeArguments[i]);
+                            }
+                            else {
+                                if (patternElement.kind !== 200 /* OmittedExpression */) {
+                                    error(patternElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
+                                }
+                                elementTypes.push(unknownType);
+                            }
+                        }
+                    }
+                    if (elementTypes.length) {
+                        return createTupleType(elementTypes);
+                    }
+                }
+            }
+            return createArrayType(elementTypes.length ?
+                getUnionType(elementTypes, /*subtypeReduction*/ true) :
+                strictNullChecks ? neverType : undefinedWideningType);
+        }
+        function isNumericName(name) {
+            switch (name.kind) {
+                case 144 /* ComputedPropertyName */:
+                    return isNumericComputedName(name);
+                case 71 /* Identifier */:
+                    return isNumericLiteralName(name.escapedText);
+                case 8 /* NumericLiteral */:
+                case 9 /* StringLiteral */:
+                    return isNumericLiteralName(name.text);
+                default:
+                    return false;
+            }
+        }
+        function isNumericComputedName(name) {
+            // It seems odd to consider an expression of type Any to result in a numeric name,
+            // but this behavior is consistent with checkIndexedAccess
+            return isTypeAssignableToKind(checkComputedPropertyName(name), 84 /* NumberLike */);
+        }
+        function isInfinityOrNaNString(name) {
+            return name === "Infinity" || name === "-Infinity" || name === "NaN";
+        }
+        function isNumericLiteralName(name) {
+            // The intent of numeric names is that
+            //     - they are names with text in a numeric form, and that
+            //     - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit',
+            //         acquired by applying the abstract 'ToNumber' operation on the name's text.
+            //
+            // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name.
+            // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold.
+            //
+            // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
+            // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
+            // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
+            // because their 'ToString' representation is not equal to their original text.
+            // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
+            //
+            // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
+            // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
+            // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
+            //
+            // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
+            // This is desired behavior, because when indexing with them as numeric entities, you are indexing
+            // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
+            return (+name).toString() === name;
+        }
+        function checkComputedPropertyName(node) {
+            var links = getNodeLinks(node.expression);
+            if (!links.resolvedType) {
+                links.resolvedType = checkExpression(node.expression);
+                // This will allow types number, string, symbol or any. It will also allow enums, the unknown
+                // type, and any union of these types (like string | number).
+                if (links.resolvedType.flags & 6144 /* Nullable */ ||
+                    !isTypeAssignableToKind(links.resolvedType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */) &&
+                        !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) {
+                    error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
+                }
+                else {
+                    checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
+                }
+            }
+            return links.resolvedType;
+        }
+        function getObjectLiteralIndexInfo(propertyNodes, offset, properties, kind) {
+            var propTypes = [];
+            for (var i = 0; i < properties.length; i++) {
+                if (kind === 0 /* String */ || isNumericName(propertyNodes[i + offset].name)) {
+                    propTypes.push(getTypeOfSymbol(properties[i]));
+                }
+            }
+            var unionType = propTypes.length ? getUnionType(propTypes, /*subtypeReduction*/ true) : undefinedType;
+            return createIndexInfo(unionType, /*isReadonly*/ false);
+        }
+        function checkObjectLiteral(node, checkMode) {
+            var inDestructuringPattern = ts.isAssignmentTarget(node);
+            // Grammar checking
+            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
+            var propertiesTable = ts.createSymbolTable();
+            var propertiesArray = [];
+            var spread = emptyObjectType;
+            var propagatedFlags = 0;
+            var contextualType = getApparentTypeOfContextualType(node);
+            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
+                (contextualType.pattern.kind === 174 /* ObjectBindingPattern */ || contextualType.pattern.kind === 178 /* ObjectLiteralExpression */);
+            var isJSObjectLiteral = !contextualType && ts.isInJavaScriptFile(node);
+            var typeFlags = 0;
+            var patternWithComputedProperties = false;
+            var hasComputedStringProperty = false;
+            var hasComputedNumberProperty = false;
+            var isInJSFile = ts.isInJavaScriptFile(node);
+            var offset = 0;
+            for (var i = 0; i < node.properties.length; i++) {
+                var memberDecl = node.properties[i];
+                var member = memberDecl.symbol;
+                var literalName = void 0;
+                if (memberDecl.kind === 261 /* PropertyAssignment */ ||
+                    memberDecl.kind === 262 /* ShorthandPropertyAssignment */ ||
+                    ts.isObjectLiteralMethod(memberDecl)) {
+                    var jsdocType = void 0;
+                    if (isInJSFile) {
+                        jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl);
+                    }
+                    var type = void 0;
+                    if (memberDecl.kind === 261 /* PropertyAssignment */) {
+                        if (memberDecl.name.kind === 144 /* ComputedPropertyName */) {
+                            var t = checkComputedPropertyName(memberDecl.name);
+                            if (t.flags & 224 /* Literal */) {
+                                literalName = ts.escapeLeadingUnderscores("" + t.value);
+                            }
+                        }
+                        type = checkPropertyAssignment(memberDecl, checkMode);
+                    }
+                    else if (memberDecl.kind === 151 /* MethodDeclaration */) {
+                        type = checkObjectLiteralMethod(memberDecl, checkMode);
+                    }
+                    else {
+                        ts.Debug.assert(memberDecl.kind === 262 /* ShorthandPropertyAssignment */);
+                        type = checkExpressionForMutableLocation(memberDecl.name, checkMode);
+                    }
+                    if (jsdocType) {
+                        checkTypeAssignableTo(type, jsdocType, memberDecl);
+                        type = jsdocType;
+                    }
+                    typeFlags |= type.flags;
+                    var prop = createSymbol(4 /* Property */ | member.flags, literalName || member.escapedName);
+                    if (inDestructuringPattern) {
+                        // If object literal is an assignment pattern and if the assignment pattern specifies a default value
+                        // for the property, make the property optional.
+                        var isOptional = (memberDecl.kind === 261 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
+                            (memberDecl.kind === 262 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
+                        if (isOptional) {
+                            prop.flags |= 16777216 /* Optional */;
+                        }
+                        if (!literalName && ts.hasDynamicName(memberDecl)) {
+                            patternWithComputedProperties = true;
+                        }
+                    }
+                    else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
+                        // If object literal is contextually typed by the implied type of a binding pattern, and if the
+                        // binding pattern specifies a default value for the property, make the property optional.
+                        var impliedProp = getPropertyOfType(contextualType, member.escapedName);
+                        if (impliedProp) {
+                            prop.flags |= impliedProp.flags & 16777216 /* Optional */;
+                        }
+                        else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) {
+                            error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
+                        }
+                    }
+                    prop.declarations = member.declarations;
+                    prop.parent = member.parent;
+                    if (member.valueDeclaration) {
+                        prop.valueDeclaration = member.valueDeclaration;
+                    }
+                    prop.type = type;
+                    prop.target = member;
+                    member = prop;
+                }
+                else if (memberDecl.kind === 263 /* SpreadAssignment */) {
+                    if (languageVersion < 2 /* ES2015 */) {
+                        checkExternalEmitHelpers(memberDecl, 2 /* Assign */);
+                    }
+                    if (propertiesArray.length > 0) {
+                        spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
+                        propertiesArray = [];
+                        propertiesTable = ts.createSymbolTable();
+                        hasComputedStringProperty = false;
+                        hasComputedNumberProperty = false;
+                        typeFlags = 0;
+                    }
+                    var type = checkExpression(memberDecl.expression);
+                    if (!isValidSpreadType(type)) {
+                        error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types);
+                        return unknownType;
+                    }
+                    spread = getSpreadType(spread, type, node.symbol, propagatedFlags);
+                    offset = i + 1;
+                    continue;
+                }
+                else {
+                    // TypeScript 1.0 spec (April 2014)
+                    // A get accessor declaration is processed in the same manner as
+                    // an ordinary function declaration(section 6.1) with no parameters.
+                    // A set accessor declaration is processed in the same manner
+                    // as an ordinary function declaration with a single parameter and a Void return type.
+                    ts.Debug.assert(memberDecl.kind === 153 /* GetAccessor */ || memberDecl.kind === 154 /* SetAccessor */);
+                    checkNodeDeferred(memberDecl);
+                }
+                if (!literalName && ts.hasDynamicName(memberDecl)) {
+                    if (isNumericName(memberDecl.name)) {
+                        hasComputedNumberProperty = true;
+                    }
+                    else {
+                        hasComputedStringProperty = true;
+                    }
+                }
+                else {
+                    propertiesTable.set(member.escapedName, member);
+                }
+                propertiesArray.push(member);
+            }
+            // If object literal is contextually typed by the implied type of a binding pattern, augment the result
+            // type with those properties for which the binding pattern specifies a default value.
+            if (contextualTypeHasPattern) {
+                for (var _i = 0, _a = getPropertiesOfType(contextualType); _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    if (!propertiesTable.get(prop.escapedName)) {
+                        if (!(prop.flags & 16777216 /* Optional */)) {
+                            error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
+                        }
+                        propertiesTable.set(prop.escapedName, prop);
+                        propertiesArray.push(prop);
+                    }
+                }
+            }
+            if (spread !== emptyObjectType) {
+                if (propertiesArray.length > 0) {
+                    spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
+                }
+                return spread;
+            }
+            return createObjectLiteralType();
+            function createObjectLiteralType() {
+                var stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 0 /* String */) : undefined;
+                var numberIndexInfo = hasComputedNumberProperty && !isJSObjectLiteral ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 1 /* Number */) : undefined;
+                var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
+                var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshLiteral */;
+                result.flags |= 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */);
+                result.objectFlags |= 128 /* ObjectLiteral */;
+                if (patternWithComputedProperties) {
+                    result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
+                }
+                if (inDestructuringPattern) {
+                    result.pattern = node;
+                }
+                if (!(result.flags & 6144 /* Nullable */)) {
+                    propagatedFlags |= (result.flags & 14680064 /* PropagatingFlags */);
+                }
+                return result;
+            }
+        }
+        function isValidSpreadType(type) {
+            return !!(type.flags & (1 /* Any */ | 16777216 /* NonPrimitive */) ||
+                getFalsyFlags(type) & 7392 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
+                type.flags & 32768 /* Object */ && !isGenericMappedType(type) ||
+                type.flags & 196608 /* UnionOrIntersection */ && !ts.forEach(type.types, function (t) { return !isValidSpreadType(t); }));
+        }
+        function checkJsxSelfClosingElement(node) {
+            checkJsxOpeningLikeElement(node);
+            return getJsxGlobalElementType() || anyType;
+        }
+        function checkJsxElement(node) {
+            // Check attributes
+            checkJsxOpeningLikeElement(node.openingElement);
+            // Perform resolution on the closing tag so that rename/go to definition/etc work
+            if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
+                getIntrinsicTagSymbol(node.closingElement);
+            }
+            else {
+                checkExpression(node.closingElement.tagName);
+            }
+            return getJsxGlobalElementType() || anyType;
+        }
+        /**
+         * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
+         */
+        function isUnhyphenatedJsxName(name) {
+            // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
+            return !ts.stringContains(name, "-");
+        }
+        /**
+         * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
+         */
+        function isJsxIntrinsicIdentifier(tagName) {
+            // TODO (yuisu): comment
+            switch (tagName.kind) {
+                case 179 /* PropertyAccessExpression */:
+                case 99 /* ThisKeyword */:
+                    return false;
+                case 71 /* Identifier */:
+                    return ts.isIntrinsicJsxName(tagName.escapedText);
+                default:
+                    ts.Debug.fail();
+            }
+        }
+        /**
+         * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
+         *
+         * @param openingLikeElement a JSX opening-like element
+         * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
+         * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
+         * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
+         * which also calls getSpreadType.
+         */
+        function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, filter, checkMode) {
+            var attributes = openingLikeElement.attributes;
+            var attributesTable = ts.createSymbolTable();
+            var spread = emptyObjectType;
+            var attributesArray = [];
+            var hasSpreadAnyType = false;
+            var typeToIntersect;
+            var explicitlySpecifyChildrenAttribute = false;
+            var jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
+            for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) {
+                var attributeDecl = _a[_i];
+                var member = attributeDecl.symbol;
+                if (ts.isJsxAttribute(attributeDecl)) {
+                    var exprType = attributeDecl.initializer ?
+                        checkExpression(attributeDecl.initializer, checkMode) :
+                        trueType; // <Elem attr /> is sugar for <Elem attr={true} />
+                    var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName);
+                    attributeSymbol.declarations = member.declarations;
+                    attributeSymbol.parent = member.parent;
+                    if (member.valueDeclaration) {
+                        attributeSymbol.valueDeclaration = member.valueDeclaration;
+                    }
+                    attributeSymbol.type = exprType;
+                    attributeSymbol.target = member;
+                    attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
+                    attributesArray.push(attributeSymbol);
+                    if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
+                        explicitlySpecifyChildrenAttribute = true;
+                    }
+                }
+                else {
+                    ts.Debug.assert(attributeDecl.kind === 255 /* JsxSpreadAttribute */);
+                    if (attributesArray.length > 0) {
+                        spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
+                        attributesArray = [];
+                        attributesTable = ts.createSymbolTable();
+                    }
+                    var exprType = checkExpression(attributeDecl.expression);
+                    if (isTypeAny(exprType)) {
+                        hasSpreadAnyType = true;
+                    }
+                    if (isValidSpreadType(exprType)) {
+                        spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*propagatedFlags*/ 0);
+                    }
+                    else {
+                        typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
+                    }
+                }
+            }
+            if (!hasSpreadAnyType) {
+                if (spread !== emptyObjectType) {
+                    if (attributesArray.length > 0) {
+                        spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
+                    }
+                    attributesArray = getPropertiesOfType(spread);
+                }
+                attributesTable = ts.createSymbolTable();
+                for (var _b = 0, attributesArray_1 = attributesArray; _b < attributesArray_1.length; _b++) {
+                    var attr = attributesArray_1[_b];
+                    if (!filter || filter(attr)) {
+                        attributesTable.set(attr.escapedName, attr);
+                    }
+                }
+            }
+            // Handle children attribute
+            var parent = openingLikeElement.parent.kind === 249 /* JsxElement */ ? openingLikeElement.parent : undefined;
+            // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
+            if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
+                var childrenTypes = [];
+                for (var _c = 0, _d = parent.children; _c < _d.length; _c++) {
+                    var child = _d[_c];
+                    // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
+                    // because then type of children property will have constituent of string type.
+                    if (child.kind === 10 /* JsxText */) {
+                        if (!child.containsOnlyWhiteSpaces) {
+                            childrenTypes.push(stringType);
+                        }
+                    }
+                    else {
+                        childrenTypes.push(checkExpression(child, checkMode));
+                    }
+                }
+                if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
+                    // Error if there is a attribute named "children" explicitly specified and children element.
+                    // This is because children element will overwrite the value from attributes.
+                    // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
+                    if (explicitlySpecifyChildrenAttribute) {
+                        error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName));
+                    }
+                    // If there are children in the body of JSX element, create dummy attribute "children" with anyType so that it will pass the attribute checking process
+                    var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName);
+                    childrenPropSymbol.type = childrenTypes.length === 1 ?
+                        childrenTypes[0] :
+                        createArrayType(getUnionType(childrenTypes, /*subtypeReduction*/ false));
+                    attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol);
+                }
+            }
+            if (hasSpreadAnyType) {
+                return anyType;
+            }
+            var attributeType = createJsxAttributesType(attributes.symbol, attributesTable);
+            return typeToIntersect && attributesTable.size ? getIntersectionType([typeToIntersect, attributeType]) :
+                typeToIntersect ? typeToIntersect : attributeType;
+            /**
+             * Create anonymous type from given attributes symbol table.
+             * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable
+             * @param attributesTable a symbol table of attributes property
+             */
+            function createJsxAttributesType(symbol, attributesTable) {
+                var result = createAnonymousType(symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
+                result.flags |= 33554432 /* JsxAttributes */ | 4194304 /* ContainsObjectLiteral */;
+                result.objectFlags |= 128 /* ObjectLiteral */;
+                return result;
+            }
+        }
+        /**
+         * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
+         * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
+         * @param node a JSXAttributes to be resolved of its type
+         */
+        function checkJsxAttributes(node, checkMode) {
+            return createJsxAttributesTypeFromAttributesProperty(node.parent, /*filter*/ undefined, checkMode);
+        }
+        function getJsxType(name) {
+            var jsxType = jsxTypes.get(name);
+            if (jsxType === undefined) {
+                jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType);
+            }
+            return jsxType;
+        }
+        /**
+         * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
+         * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
+         * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
+         * May also return unknownSymbol if both of these lookups fail.
+         */
+        function getIntrinsicTagSymbol(node) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedSymbol) {
+                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
+                if (intrinsicElementsType !== unknownType) {
+                    // Property case
+                    if (!ts.isIdentifier(node.tagName))
+                        throw ts.Debug.fail();
+                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText);
+                    if (intrinsicProp) {
+                        links.jsxFlags |= 1 /* IntrinsicNamedElement */;
+                        return links.resolvedSymbol = intrinsicProp;
+                    }
+                    // Intrinsic string indexer case
+                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
+                    if (indexSignatureType) {
+                        links.jsxFlags |= 2 /* IntrinsicIndexedElement */;
+                        return links.resolvedSymbol = intrinsicElementsType.symbol;
+                    }
+                    // Wasn't found
+                    error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements);
+                    return links.resolvedSymbol = unknownSymbol;
+                }
+                else {
+                    if (noImplicitAny) {
+                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements));
+                    }
+                    return links.resolvedSymbol = unknownSymbol;
+                }
+            }
+            return links.resolvedSymbol;
+        }
+        /**
+         * Given a JSX element that is a class element, finds the Element Instance Type. If the
+         * element is not a class element, or the class element type cannot be determined, returns 'undefined'.
+         * For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
+         */
+        function getJsxElementInstanceType(node, valueType) {
+            ts.Debug.assert(!(valueType.flags & 65536 /* Union */));
+            if (isTypeAny(valueType)) {
+                // Short-circuit if the class tag is using an element type 'any'
+                return anyType;
+            }
+            // Resolve the signatures, preferring constructor
+            var signatures = getSignaturesOfType(valueType, 1 /* Construct */);
+            if (signatures.length === 0) {
+                // No construct signatures, try call signatures
+                signatures = getSignaturesOfType(valueType, 0 /* Call */);
+                if (signatures.length === 0) {
+                    // We found no signatures at all, which is an error
+                    error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName));
+                    return unknownType;
+                }
+            }
+            var instantiatedSignatures = [];
+            for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) {
+                var signature = signatures_3[_i];
+                if (signature.typeParameters) {
+                    var isJavascript = ts.isInJavaScriptFile(node);
+                    var typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript);
+                    instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
+                }
+                else {
+                    instantiatedSignatures.push(signature);
+                }
+            }
+            return getUnionType(ts.map(instantiatedSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
+        }
+        /**
+         * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
+         * Get a single property from that container if existed. Report an error if there are more than one property.
+         *
+         * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
+         *          if other string is given or the container doesn't exist, return undefined.
+         */
+        function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer) {
+            // JSX
+            var jsxNamespace = getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined);
+            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
+            var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 793064 /* Type */);
+            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
+            var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
+            // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
+            var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
+            if (propertiesOfJsxElementAttribPropInterface) {
+                // Element Attributes has zero properties, so the element attributes type will be the class instance type
+                if (propertiesOfJsxElementAttribPropInterface.length === 0) {
+                    return "";
+                }
+                else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
+                    return propertiesOfJsxElementAttribPropInterface[0].escapedName;
+                }
+                else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
+                    // More than one property on ElementAttributesProperty is an error
+                    error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer));
+                }
+            }
+            return undefined;
+        }
+        /// e.g. "props" for React.d.ts,
+        /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
+        ///     non-intrinsic elements' attributes type is 'any'),
+        /// or '' if it has 0 properties (which means every
+        ///     non-intrinsic elements' attributes type is the element instance type)
+        function getJsxElementPropertiesName() {
+            if (!_hasComputedJsxElementPropertiesName) {
+                _hasComputedJsxElementPropertiesName = true;
+                _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer);
+            }
+            return _jsxElementPropertiesName;
+        }
+        function getJsxElementChildrenPropertyname() {
+            if (!_hasComputedJsxElementChildrenPropertyName) {
+                _hasComputedJsxElementChildrenPropertyName = true;
+                _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer);
+            }
+            return _jsxElementChildrenPropertyName;
+        }
+        function getApparentTypeOfJsxPropsType(propsType) {
+            if (!propsType) {
+                return undefined;
+            }
+            if (propsType.flags & 131072 /* Intersection */) {
+                var propsApparentType = [];
+                for (var _i = 0, _a = propsType.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    propsApparentType.push(getApparentType(t));
+                }
+                return getIntersectionType(propsApparentType);
+            }
+            return getApparentType(propsType);
+        }
+        /**
+         * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
+         * Return only attributes type of successfully resolved call signature.
+         * This function assumes that the caller handled other possible element type of the JSX element (e.g. stateful component)
+         * Unlike tryGetAllJsxStatelessFunctionAttributesType, this function is a default behavior of type-checkers.
+         * @param openingLikeElement a JSX opening-like element to find attributes type
+         * @param elementType a type of the opening-like element. This elementType can't be an union type
+         * @param elemInstanceType an element instance type (the result of newing or invoking this tag)
+         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global
+         */
+        function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) {
+            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
+            if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
+                var jsxStatelessElementType = getJsxGlobalStatelessElementType();
+                if (jsxStatelessElementType) {
+                    // We don't call getResolvedSignature here because we have already resolve the type of JSX Element.
+                    var callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
+                    if (callSignature !== unknownSignature) {
+                        var callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
+                        var paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
+                        paramType = getApparentTypeOfJsxPropsType(paramType);
+                        if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
+                            // Intersect in JSX.IntrinsicAttributes if it exists
+                            var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
+                            if (intrinsicAttributes !== unknownType) {
+                                paramType = intersectTypes(intrinsicAttributes, paramType);
+                            }
+                            return paramType;
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        /**
+         * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
+         * Return all attributes type of resolved call signature including candidate signatures.
+         * This function assumes that the caller handled other possible element type of the JSX element.
+         * This function is a behavior used by language service when looking up completion in JSX element.
+         * @param openingLikeElement a JSX opening-like element to find attributes type
+         * @param elementType a type of the opening-like element. This elementType can't be an union type
+         * @param elemInstanceType an element instance type (the result of newing or invoking this tag)
+         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global
+         */
+        function tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) {
+            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
+            if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
+                // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
+                var jsxStatelessElementType = getJsxGlobalStatelessElementType();
+                if (jsxStatelessElementType) {
+                    // We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
+                    var candidatesOutArray = [];
+                    getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray);
+                    var result = void 0;
+                    var allMatchingAttributesType = void 0;
+                    for (var _i = 0, candidatesOutArray_1 = candidatesOutArray; _i < candidatesOutArray_1.length; _i++) {
+                        var candidate = candidatesOutArray_1[_i];
+                        var callReturnType = getReturnTypeOfSignature(candidate);
+                        var paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0]));
+                        paramType = getApparentTypeOfJsxPropsType(paramType);
+                        if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
+                            var shouldBeCandidate = true;
+                            for (var _a = 0, _b = openingLikeElement.attributes.properties; _a < _b.length; _a++) {
+                                var attribute = _b[_a];
+                                if (ts.isJsxAttribute(attribute) &&
+                                    isUnhyphenatedJsxName(attribute.name.escapedText) &&
+                                    !getPropertyOfType(paramType, attribute.name.escapedText)) {
+                                    shouldBeCandidate = false;
+                                    break;
+                                }
+                            }
+                            if (shouldBeCandidate) {
+                                result = intersectTypes(result, paramType);
+                            }
+                            allMatchingAttributesType = intersectTypes(allMatchingAttributesType, paramType);
+                        }
+                    }
+                    // If we can't find any matching, just return everything.
+                    if (!result) {
+                        result = allMatchingAttributesType;
+                    }
+                    // Intersect in JSX.IntrinsicAttributes if it exists
+                    var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
+                    if (intrinsicAttributes !== unknownType) {
+                        result = intersectTypes(intrinsicAttributes, result);
+                    }
+                    return result;
+                }
+            }
+            return undefined;
+        }
+        /**
+         * Resolve attributes type of the given opening-like element. The attributes type is a type of attributes associated with the given elementType.
+         * For instance:
+         *      declare function Foo(attr: { p1: string}): JSX.Element;
+         *      <Foo p1={10} />;  // This function will try resolve "Foo" and return an attributes type of "Foo" which is "{ p1: string }"
+         *
+         * The function is intended to initially be called from getAttributesTypeFromJsxOpeningLikeElement which already handle JSX-intrinsic-element..
+         * This function will try to resolve custom JSX attributes type in following order: string literal, stateless function, and stateful component
+         *
+         * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement
+         * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature
+         * @param elementType an instance type of the given opening-like element. If undefined, the function will check type openinglikeElement's tagname.
+         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts)
+         * @return attributes type if able to resolve the type of node
+         *         anyType if there is no type ElementAttributesProperty or there is an error
+         *         emptyObjectType if there is no "prop" in the element instance type
+         */
+        function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) {
+            if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); }
+            if (elementType.flags & 65536 /* Union */) {
+                var types = elementType.types;
+                return getUnionType(types.map(function (type) {
+                    return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType);
+                }), /*subtypeReduction*/ true);
+            }
+            // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type
+            if (elementType.flags & 2 /* String */) {
+                return anyType;
+            }
+            else if (elementType.flags & 32 /* StringLiteral */) {
+                // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type
+                // For example:
+                //      var CustomTag: "h1" = "h1";
+                //      <CustomTag> Hello World </CustomTag>
+                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
+                if (intrinsicElementsType !== unknownType) {
+                    var stringLiteralTypeName = elementType.value;
+                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName));
+                    if (intrinsicProp) {
+                        return getTypeOfSymbol(intrinsicProp);
+                    }
+                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
+                    if (indexSignatureType) {
+                        return indexSignatureType;
+                    }
+                    error(openingLikeElement, ts.Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements);
+                }
+                // If we need to report an error, we already done so here. So just return any to prevent any more error downstream
+                return anyType;
+            }
+            // Get the element instance type (the result of newing or invoking this tag)
+            var elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType);
+            // If we should include all stateless attributes type, then get all attributes type from all stateless function signature.
+            // Otherwise get only attributes type from the signature picked by choose-overload logic.
+            var statelessAttributesType = shouldIncludeAllStatelessAttributesType ?
+                tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) :
+                defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType);
+            if (statelessAttributesType) {
+                return statelessAttributesType;
+            }
+            // Issue an error if this return type isn't assignable to JSX.ElementClass
+            if (elementClassType) {
+                checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
+            }
+            if (isTypeAny(elemInstanceType)) {
+                return elemInstanceType;
+            }
+            var propsName = getJsxElementPropertiesName();
+            if (propsName === undefined) {
+                // There is no type ElementAttributesProperty, return 'any'
+                return anyType;
+            }
+            else if (propsName === "") {
+                // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
+                return elemInstanceType;
+            }
+            else {
+                var attributesType = getTypeOfPropertyOfType(elemInstanceType, propsName);
+                if (!attributesType) {
+                    // There is no property named 'props' on this instance type
+                    return emptyObjectType;
+                }
+                else if (isTypeAny(attributesType) || (attributesType === unknownType)) {
+                    // Props is of type 'any' or unknown
+                    return attributesType;
+                }
+                else {
+                    // Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
+                    var apparentAttributesType = attributesType;
+                    var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes);
+                    if (intrinsicClassAttribs !== unknownType) {
+                        var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
+                        if (typeParams) {
+                            if (typeParams.length === 1) {
+                                apparentAttributesType = intersectTypes(createTypeReference(intrinsicClassAttribs, [elemInstanceType]), apparentAttributesType);
+                            }
+                        }
+                        else {
+                            apparentAttributesType = intersectTypes(attributesType, intrinsicClassAttribs);
+                        }
+                    }
+                    var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes);
+                    if (intrinsicAttribs !== unknownType) {
+                        apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
+                    }
+                    return apparentAttributesType;
+                }
+            }
+        }
+        /**
+         * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name.
+         * The function is intended to be called from a function which has checked that the opening element is an intrinsic element.
+         * @param node an intrinsic JSX opening-like element
+         */
+        function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) {
+            ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName));
+            var links = getNodeLinks(node);
+            if (!links.resolvedJsxElementAttributesType) {
+                var symbol = getIntrinsicTagSymbol(node);
+                if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
+                    return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol);
+                }
+                else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
+                    return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, 0 /* String */).type;
+                }
+                else {
+                    return links.resolvedJsxElementAttributesType = unknownType;
+                }
+            }
+            return links.resolvedJsxElementAttributesType;
+        }
+        /**
+         * Get attributes type of the given custom opening-like JSX element.
+         * This function is intended to be called from a caller that handles intrinsic JSX element already.
+         * @param node a custom JSX opening-like element
+         * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component
+         */
+        function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) {
+            var links = getNodeLinks(node);
+            var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType";
+            if (!links[linkLocation]) {
+                var elemClassType = getJsxGlobalElementClassType();
+                return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType);
+            }
+            return links[linkLocation];
+        }
+        /**
+         * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element.
+         * This function is called by language service (see: completions-tryGetGlobalSymbols).
+         * @param node a JSX opening-like element to get attributes type for
+         */
+        function getAllAttributesTypeFromJsxOpeningLikeElement(node) {
+            if (isJsxIntrinsicIdentifier(node.tagName)) {
+                return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
+            }
+            else {
+                // Because in language service, the given JSX opening-like element may be incomplete and therefore,
+                // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads.
+                return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true);
+            }
+        }
+        /**
+         * Get the attributes type, which indicates the attributes that are valid on the given JSXOpeningLikeElement.
+         * @param node a JSXOpeningLikeElement node
+         * @return an attributes type of the given node
+         */
+        function getAttributesTypeFromJsxOpeningLikeElement(node) {
+            if (isJsxIntrinsicIdentifier(node.tagName)) {
+                return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
+            }
+            else {
+                return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false);
+            }
+        }
+        /**
+         * Given a JSX attribute, returns the symbol for the corresponds property
+         * of the element attributes type. Will return unknownSymbol for attributes
+         * that have no matching element attributes type property.
+         */
+        function getJsxAttributePropertySymbol(attrib) {
+            var attributesType = getAttributesTypeFromJsxOpeningLikeElement(attrib.parent.parent);
+            var prop = getPropertyOfType(attributesType, attrib.name.escapedText);
+            return prop || unknownSymbol;
+        }
+        function getJsxGlobalElementClassType() {
+            if (!deferredJsxElementClassType) {
+                deferredJsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
+            }
+            return deferredJsxElementClassType;
+        }
+        function getJsxGlobalElementType() {
+            if (!deferredJsxElementType) {
+                deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element);
+            }
+            return deferredJsxElementType;
+        }
+        function getJsxGlobalStatelessElementType() {
+            if (!deferredJsxStatelessElementType) {
+                var jsxElementType = getJsxGlobalElementType();
+                if (jsxElementType) {
+                    deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]);
+                }
+            }
+            return deferredJsxStatelessElementType;
+        }
+        /**
+         * Returns all the properties of the Jsx.IntrinsicElements interface
+         */
+        function getJsxIntrinsicTagNames() {
+            var intrinsics = getJsxType(JsxNames.IntrinsicElements);
+            return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray;
+        }
+        function checkJsxPreconditions(errorNode) {
+            // Preconditions for using JSX
+            if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) {
+                error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
+            }
+            if (getJsxGlobalElementType() === undefined) {
+                if (noImplicitAny) {
+                    error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
+                }
+            }
+        }
+        function checkJsxOpeningLikeElement(node) {
+            checkGrammarJsxElement(node);
+            checkJsxPreconditions(node);
+            // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
+            // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
+            var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
+            var reactNamespace = getJsxNamespace();
+            var reactSym = resolveName(node.tagName, reactNamespace, 107455 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true);
+            if (reactSym) {
+                // Mark local symbol as referenced here because it might not have been marked
+                // if jsx emit was not react as there wont be error being emitted
+                reactSym.isReferenced = true;
+                // If react symbol is alias, mark it as refereced
+                if (reactSym.flags & 2097152 /* Alias */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) {
+                    markAliasSymbolAsReferenced(reactSym);
+                }
+            }
+            checkJsxAttributesAssignableToTagNameAttributes(node);
+        }
+        /**
+         * Check if a property with the given name is known anywhere in the given type. In an object type, a property
+         * is considered known if
+         * 1. the object type is empty and the check is for assignability, or
+         * 2. if the object type has index signatures, or
+         * 3. if the property is actually declared in the object type
+         *    (this means that 'toString', for example, is not usually a known property).
+         * 4. In a union or intersection type,
+         *    a property is considered known if it is known in any constituent type.
+         * @param targetType a type to search a given name in
+         * @param name a property name to search
+         * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
+         */
+        function isKnownProperty(targetType, name, isComparingJsxAttributes) {
+            if (targetType.flags & 32768 /* Object */) {
+                var resolved = resolveStructuredTypeMembers(targetType);
+                if (resolved.stringIndexInfo ||
+                    resolved.numberIndexInfo && isNumericLiteralName(name) ||
+                    getPropertyOfObjectType(targetType, name) ||
+                    isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
+                    // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
+                    return true;
+                }
+            }
+            else if (targetType.flags & 196608 /* UnionOrIntersection */) {
+                for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    if (isKnownProperty(t, name, isComparingJsxAttributes)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        /**
+         * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes.
+         *      Get the attributes type of the opening-like element through resolving the tagName, "target attributes"
+         *      Check assignablity between given attributes property, "source attributes", and the "target attributes"
+         * @param openingLikeElement an opening-like JSX element to check its JSXAttributes
+         */
+        function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement) {
+            // The function involves following steps:
+            //      1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType.
+            //         During these steps, we will try to resolve the tagName as intrinsic name, stateless function, stateful component (in the order)
+            //      2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element.
+            //      3. Check if the two are assignable to each other
+            // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element.
+            var targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ?
+                getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) :
+                getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false);
+            // sourceAttributesType is a type of an attributes properties.
+            // i.e <div attr1={10} attr2="string" />
+            //     attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes".
+            var sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, function (attribute) {
+                return isUnhyphenatedJsxName(attribute.escapedName) || !!(getPropertyOfType(targetAttributesType, attribute.escapedName));
+            });
+            // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
+            // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass.
+            if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || sourceAttributesType.properties.length > 0)) {
+                error(openingLikeElement, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(getJsxElementPropertiesName()));
+            }
+            else {
+                // Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties
+                var isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
+                // After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType.
+                // This will allow excess properties in spread type as it is very common pattern to spread outter attributes into React component in its render method.
+                if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) {
+                    for (var _i = 0, _a = openingLikeElement.attributes.properties; _i < _a.length; _i++) {
+                        var attribute = _a[_i];
+                        if (ts.isJsxAttribute(attribute) && !isKnownProperty(targetAttributesType, attribute.name.escapedText, /*isComparingJsxAttributes*/ true)) {
+                            error(attribute, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(attribute.name), typeToString(targetAttributesType));
+                            // We break here so that errors won't be cascading
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        function checkJsxExpression(node, checkMode) {
+            if (node.expression) {
+                var type = checkExpression(node.expression, checkMode);
+                if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
+                    error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type);
+                }
+                return type;
+            }
+            else {
+                return unknownType;
+            }
+        }
+        // If a symbol is a synthesized symbol with no value declaration, we assume it is a property. Example of this are the synthesized
+        // '.prototype' property as well as synthesized tuple index properties.
+        function getDeclarationKindFromSymbol(s) {
+            return s.valueDeclaration ? s.valueDeclaration.kind : 149 /* PropertyDeclaration */;
+        }
+        function getDeclarationNodeFlagsFromSymbol(s) {
+            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0;
+        }
+        function isMethodLike(symbol) {
+            return !!(symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */);
+        }
+        /**
+         * Check whether the requested property access is valid.
+         * Returns true if node is a valid property access, and false otherwise.
+         * @param node The node to be checked.
+         * @param left The left hand side of the property access (e.g.: the super in `super.foo`).
+         * @param type The type of left.
+         * @param prop The symbol for the right hand side of the property access.
+         */
+        function checkPropertyAccessibility(node, left, type, prop) {
+            var flags = ts.getDeclarationModifierFlagsFromSymbol(prop);
+            var errorNode = node.kind === 179 /* PropertyAccessExpression */ || node.kind === 226 /* VariableDeclaration */ ?
+                node.name :
+                node.right;
+            if (ts.getCheckFlags(prop) & 256 /* ContainsPrivate */) {
+                // Synthetic property with private constituent property
+                error(errorNode, ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(prop), typeToString(type));
+                return false;
+            }
+            if (left.kind === 97 /* SuperKeyword */) {
+                // TS 1.0 spec (April 2014): 4.8.2
+                // - In a constructor, instance member function, instance member accessor, or
+                //   instance member variable initializer where this references a derived class instance,
+                //   a super property access is permitted and must specify a public instance member function of the base class.
+                // - In a static member function or static member accessor
+                //   where this references the constructor function object of a derived class,
+                //   a super property access is permitted and must specify a public static member function of the base class.
+                if (languageVersion < 2 /* ES2015 */) {
+                    var hasNonMethodDeclaration = forEachProperty(prop, function (p) {
+                        var propKind = getDeclarationKindFromSymbol(p);
+                        return propKind !== 151 /* MethodDeclaration */ && propKind !== 150 /* MethodSignature */;
+                    });
+                    if (hasNonMethodDeclaration) {
+                        error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
+                        return false;
+                    }
+                }
+                if (flags & 128 /* Abstract */) {
+                    // A method cannot be accessed in a super property access if the method is abstract.
+                    // This error could mask a private property access error. But, a member
+                    // cannot simultaneously be private and abstract, so this will trigger an
+                    // additional error elsewhere.
+                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)));
+                    return false;
+                }
+            }
+            // Public properties are otherwise accessible.
+            if (!(flags & 24 /* NonPublicAccessibilityModifier */)) {
+                return true;
+            }
+            // Property is known to be private or protected at this point
+            // Private property is accessible if the property is within the declaring class
+            if (flags & 8 /* Private */) {
+                var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
+                if (!isNodeWithinClass(node, declaringClassDeclaration)) {
+                    error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)));
+                    return false;
+                }
+                return true;
+            }
+            // Property is known to be protected at this point
+            // All protected properties of a supertype are accessible in a super access
+            if (left.kind === 97 /* SuperKeyword */) {
+                return true;
+            }
+            // Find the first enclosing class that has the declaring classes of the protected constituents
+            // of the property as base classes
+            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
+                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
+                return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
+            });
+            // A protected property is accessible if the property is within the declaring class or classes derived from it
+            if (!enclosingClass) {
+                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type));
+                return false;
+            }
+            // No further restrictions for static properties
+            if (flags & 32 /* Static */) {
+                return true;
+            }
+            // An instance property must be accessed through an instance of the enclosing class
+            if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
+                // get the original type -- represented as the type constraint of the 'this' type
+                type = getConstraintOfTypeParameter(type);
+            }
+            if (!(getObjectFlags(getTargetType(type)) & 3 /* ClassOrInterface */ && hasBaseType(type, enclosingClass))) {
+                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
+                return false;
+            }
+            return true;
+        }
+        function checkNonNullExpression(node) {
+            return checkNonNullType(checkExpression(node), node);
+        }
+        function checkNonNullType(type, errorNode) {
+            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 6144 /* Nullable */;
+            if (kind) {
+                error(errorNode, kind & 2048 /* Undefined */ ? kind & 4096 /* Null */ ?
+                    ts.Diagnostics.Object_is_possibly_null_or_undefined :
+                    ts.Diagnostics.Object_is_possibly_undefined :
+                    ts.Diagnostics.Object_is_possibly_null);
+                var t = getNonNullableType(type);
+                return t.flags & (6144 /* Nullable */ | 8192 /* Never */) ? unknownType : t;
+            }
+            return type;
+        }
+        function checkPropertyAccessExpression(node) {
+            return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name);
+        }
+        function checkQualifiedName(node) {
+            return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right);
+        }
+        function checkPropertyAccessExpressionOrQualifiedName(node, left, right) {
+            var type = checkNonNullExpression(left);
+            if (isTypeAny(type) || type === silentNeverType) {
+                return type;
+            }
+            var apparentType = getApparentType(getWidenedType(type));
+            if (apparentType === unknownType || (type.flags & 16384 /* TypeParameter */ && isTypeAny(apparentType))) {
+                // handle cases when type is Type parameter with invalid or any constraint
+                return apparentType;
+            }
+            var prop = getPropertyOfType(apparentType, right.escapedText);
+            if (!prop) {
+                var indexInfo = getIndexInfoOfType(apparentType, 0 /* String */);
+                if (indexInfo && indexInfo.type) {
+                    if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) {
+                        error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
+                    }
+                    return indexInfo.type;
+                }
+                if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
+                    reportNonexistentProperty(right, type.flags & 16384 /* TypeParameter */ && type.isThisType ? apparentType : type);
+                }
+                return unknownType;
+            }
+            checkPropertyNotUsedBeforeDeclaration(prop, node, right);
+            markPropertyAsReferenced(prop, node, left.kind === 99 /* ThisKeyword */);
+            getNodeLinks(node).resolvedSymbol = prop;
+            checkPropertyAccessibility(node, left, apparentType, prop);
+            var propType = getDeclaredOrApparentType(prop, node);
+            var assignmentKind = ts.getAssignmentTargetKind(node);
+            if (assignmentKind) {
+                if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) {
+                    error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, ts.idText(right));
+                    return unknownType;
+                }
+            }
+            // Only compute control flow type if this is a property access expression that isn't an
+            // assignment target, and the referenced property was declared as a variable, property,
+            // accessor, or optional method.
+            if (node.kind !== 179 /* PropertyAccessExpression */ || assignmentKind === 1 /* Definite */ ||
+                !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) &&
+                    !(prop.flags & 8192 /* Method */ && propType.flags & 65536 /* Union */)) {
+                return propType;
+            }
+            var flowType = getFlowTypeOfReference(node, propType);
+            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
+        }
+        function checkPropertyNotUsedBeforeDeclaration(prop, node, right) {
+            var valueDeclaration = prop.valueDeclaration;
+            if (!valueDeclaration) {
+                return;
+            }
+            if (isInPropertyInitializer(node) &&
+                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
+                && !isPropertyDeclaredInAncestorClass(prop)) {
+                error(right, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.idText(right));
+            }
+            else if (valueDeclaration.kind === 229 /* ClassDeclaration */ &&
+                node.parent.kind !== 159 /* TypeReference */ &&
+                !ts.isInAmbientContext(valueDeclaration) &&
+                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
+                error(right, ts.Diagnostics.Class_0_used_before_its_declaration, ts.idText(right));
+            }
+        }
+        function isInPropertyInitializer(node) {
+            return !!ts.findAncestor(node, function (node) {
+                switch (node.kind) {
+                    case 149 /* PropertyDeclaration */:
+                        return true;
+                    case 261 /* PropertyAssignment */:
+                        // We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`.
+                        return false;
+                    default:
+                        return ts.isPartOfExpression(node) ? false : "quit";
+                }
+            });
+        }
+        /**
+         * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass.
+         * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration.
+         */
+        function isPropertyDeclaredInAncestorClass(prop) {
+            var classType = getTypeOfSymbol(prop.parent);
+            while (true) {
+                classType = getSuperClass(classType);
+                if (!classType) {
+                    return false;
+                }
+                var superProperty = getPropertyOfObjectType(classType, prop.escapedName);
+                if (superProperty && superProperty.valueDeclaration) {
+                    return true;
+                }
+            }
+        }
+        function getSuperClass(classType) {
+            var x = getBaseTypes(classType);
+            if (x.length === 0) {
+                return undefined;
+            }
+            ts.Debug.assert(x.length === 1);
+            return x[0];
+        }
+        function reportNonexistentProperty(propNode, containingType) {
+            var errorInfo;
+            if (containingType.flags & 65536 /* Union */ && !(containingType.flags & 8190 /* Primitive */)) {
+                for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
+                    var subtype = _a[_i];
+                    if (!getPropertyOfType(subtype, propNode.escapedText)) {
+                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype));
+                        break;
+                    }
+                }
+            }
+            var suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
+            if (suggestion !== undefined) {
+                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestion);
+            }
+            else {
+                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
+            }
+            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
+        }
+        function getSuggestionForNonexistentProperty(node, containingType) {
+            var suggestion = getSpellingSuggestionForName(ts.idText(node), getPropertiesOfType(containingType), 107455 /* Value */);
+            return suggestion && ts.symbolName(suggestion);
+        }
+        function getSuggestionForNonexistentSymbol(location, name, meaning) {
+            var result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, function (symbols, name, meaning) {
+                // `name` from the callback === the outer `name`
+                var symbol = getSymbol(symbols, name, meaning);
+                // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
+                // So the table *contains* `x` but `x` isn't actually in scope.
+                // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
+                return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning);
+            });
+            return result && ts.symbolName(result);
+        }
+        /**
+         * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
+         * Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
+         *
+         * If there is a candidate that's the same except for case, return that.
+         * If there is a candidate that's within one edit of the name, return that.
+         * Otherwise, return the candidate with the smallest Levenshtein distance,
+         *    except for candidates:
+         *      * With no name
+         *      * Whose meaning doesn't match the `meaning` parameter.
+         *      * Whose length differs from the target name by more than 0.3 of the length of the name.
+         *      * Whose levenshtein distance is more than 0.4 of the length of the name
+         *        (0.4 allows 1 substitution/transposition for every 5 characters,
+         *         and 1 insertion/deletion at 3 characters)
+         * Names longer than 30 characters don't get suggestions because Levenshtein distance is an n**2 algorithm.
+         */
+        function getSpellingSuggestionForName(name, symbols, meaning) {
+            var worstDistance = name.length * 0.4;
+            var maximumLengthDifference = Math.min(3, name.length * 0.34);
+            var bestDistance = Number.MAX_VALUE;
+            var bestCandidate = undefined;
+            var justCheckExactMatches = false;
+            if (name.length > 30) {
+                return undefined;
+            }
+            name = name.toLowerCase();
+            for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
+                var candidate = symbols_3[_i];
+                var candidateName = ts.symbolName(candidate);
+                if (candidate.flags & meaning &&
+                    candidateName &&
+                    Math.abs(candidateName.length - name.length) < maximumLengthDifference) {
+                    candidateName = candidateName.toLowerCase();
+                    if (candidateName === name) {
+                        return candidate;
+                    }
+                    if (justCheckExactMatches) {
+                        continue;
+                    }
+                    if (candidateName.length < 3 ||
+                        name.length < 3 ||
+                        candidateName === "eval" ||
+                        candidateName === "intl" ||
+                        candidateName === "undefined" ||
+                        candidateName === "map" ||
+                        candidateName === "nan" ||
+                        candidateName === "set") {
+                        continue;
+                    }
+                    var distance = ts.levenshtein(name, candidateName);
+                    if (distance > worstDistance) {
+                        continue;
+                    }
+                    if (distance < 3) {
+                        justCheckExactMatches = true;
+                        bestCandidate = candidate;
+                    }
+                    else if (distance < bestDistance) {
+                        bestDistance = distance;
+                        bestCandidate = candidate;
+                    }
+                }
+            }
+            return bestCandidate;
+        }
+        function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) {
+            if (prop &&
+                noUnusedIdentifiers &&
+                (prop.flags & 106500 /* ClassMember */) &&
+                prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8 /* Private */)
+                && !(nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly))) {
+                if (isThisAccess) {
+                    // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
+                    var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration);
+                    if (containingMethod && containingMethod.symbol === prop) {
+                        return;
+                    }
+                }
+                if (ts.getCheckFlags(prop) & 1 /* Instantiated */) {
+                    getSymbolLinks(prop).target.isReferenced = true;
+                }
+                else {
+                    prop.isReferenced = true;
+                }
+            }
+        }
+        function isValidPropertyAccess(node, propertyName) {
+            var left = node.kind === 179 /* PropertyAccessExpression */
+                ? node.expression
+                : node.left;
+            return isValidPropertyAccessWithType(node, left, propertyName, getWidenedType(checkExpression(left)));
+        }
+        function isValidPropertyAccessWithType(node, left, propertyName, type) {
+            if (type !== unknownType && !isTypeAny(type)) {
+                var prop = getPropertyOfType(type, propertyName);
+                if (prop) {
+                    return checkPropertyAccessibility(node, left, type, prop);
+                }
+                // In js files properties of unions are allowed in completion
+                if (ts.isInJavaScriptFile(left) && (type.flags & 65536 /* Union */)) {
+                    for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                        var elementType = _a[_i];
+                        if (isValidPropertyAccessWithType(node, left, propertyName, elementType)) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            }
+            return true;
+        }
+        /**
+         * Return the symbol of the for-in variable declared or referenced by the given for-in statement.
+         */
+        function getForInVariableSymbol(node) {
+            var initializer = node.initializer;
+            if (initializer.kind === 227 /* VariableDeclarationList */) {
+                var variable = initializer.declarations[0];
+                if (variable && !ts.isBindingPattern(variable.name)) {
+                    return getSymbolOfNode(variable);
+                }
+            }
+            else if (initializer.kind === 71 /* Identifier */) {
+                return getResolvedSymbol(initializer);
+            }
+            return undefined;
+        }
+        /**
+         * Return true if the given type is considered to have numeric property names.
+         */
+        function hasNumericPropertyNames(type) {
+            return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */);
+        }
+        /**
+         * Return true if given node is an expression consisting of an identifier (possibly parenthesized)
+         * that references a for-in variable for an object with numeric property names.
+         */
+        function isForInVariableForNumericPropertyNames(expr) {
+            var e = ts.skipParentheses(expr);
+            if (e.kind === 71 /* Identifier */) {
+                var symbol = getResolvedSymbol(e);
+                if (symbol.flags & 3 /* Variable */) {
+                    var child = expr;
+                    var node = expr.parent;
+                    while (node) {
+                        if (node.kind === 215 /* ForInStatement */ &&
+                            child === node.statement &&
+                            getForInVariableSymbol(node) === symbol &&
+                            hasNumericPropertyNames(getTypeOfExpression(node.expression))) {
+                            return true;
+                        }
+                        child = node;
+                        node = node.parent;
+                    }
+                }
+            }
+            return false;
+        }
+        function checkIndexedAccess(node) {
+            var objectType = checkNonNullExpression(node.expression);
+            var indexExpression = node.argumentExpression;
+            if (!indexExpression) {
+                var sourceFile = ts.getSourceFileOfNode(node);
+                if (node.parent.kind === 182 /* NewExpression */ && node.parent.expression === node) {
+                    var start = ts.skipTrivia(sourceFile.text, node.expression.end);
+                    var end = node.end;
+                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead);
+                }
+                else {
+                    var start = node.end - "]".length;
+                    var end = node.end;
+                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Expression_expected);
+                }
+                return unknownType;
+            }
+            var indexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : checkExpression(indexExpression);
+            if (objectType === unknownType || objectType === silentNeverType) {
+                return objectType;
+            }
+            if (isConstEnumObjectType(objectType) && indexExpression.kind !== 9 /* StringLiteral */) {
+                error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
+                return unknownType;
+            }
+            return checkIndexedAccessIndexType(getIndexedAccessType(objectType, indexType, node), node);
+        }
+        function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) {
+            if (expressionType === unknownType) {
+                // There is already an error, so no need to report one.
+                return false;
+            }
+            if (!ts.isWellKnownSymbolSyntactically(expression)) {
+                return false;
+            }
+            // Make sure the property type is the primitive symbol type
+            if ((expressionType.flags & 512 /* ESSymbol */) === 0) {
+                if (reportError) {
+                    error(expression, ts.Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, ts.getTextOfNode(expression));
+                }
+                return false;
+            }
+            // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
+            // global Symbol object
+            var leftHandSide = expression.expression;
+            var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
+            if (!leftHandSideSymbol) {
+                return false;
+            }
+            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
+            if (!globalESSymbol) {
+                // Already errored when we tried to look up the symbol
+                return false;
+            }
+            if (leftHandSideSymbol !== globalESSymbol) {
+                if (reportError) {
+                    error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
+                }
+                return false;
+            }
+            return true;
+        }
+        function callLikeExpressionMayHaveTypeArguments(node) {
+            // TODO: Also include tagged templates (https://github.com/Microsoft/TypeScript/issues/11947)
+            return ts.isCallOrNewExpression(node);
+        }
+        function resolveUntypedCall(node) {
+            if (callLikeExpressionMayHaveTypeArguments(node)) {
+                // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
+                // This gets us diagnostics for the type arguments and marks them as referenced.
+                ts.forEach(node.typeArguments, checkSourceElement);
+            }
+            if (node.kind === 183 /* TaggedTemplateExpression */) {
+                checkExpression(node.template);
+            }
+            else if (node.kind !== 147 /* Decorator */) {
+                ts.forEach(node.arguments, function (argument) {
+                    checkExpression(argument);
+                });
+            }
+            return anySignature;
+        }
+        function resolveErrorCall(node) {
+            resolveUntypedCall(node);
+            return unknownSignature;
+        }
+        // Re-order candidate signatures into the result array. Assumes the result array to be empty.
+        // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
+        // A nit here is that we reorder only signatures that belong to the same symbol,
+        // so order how inherited signatures are processed is still preserved.
+        // interface A { (x: string): void }
+        // interface B extends A { (x: 'foo'): string }
+        // const b: B;
+        // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
+        function reorderCandidates(signatures, result) {
+            var lastParent;
+            var lastSymbol;
+            var cutoffIndex = 0;
+            var index;
+            var specializedIndex = -1;
+            var spliceIndex;
+            ts.Debug.assert(!result.length);
+            for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) {
+                var signature = signatures_4[_i];
+                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
+                var parent = signature.declaration && signature.declaration.parent;
+                if (!lastSymbol || symbol === lastSymbol) {
+                    if (lastParent && parent === lastParent) {
+                        index++;
+                    }
+                    else {
+                        lastParent = parent;
+                        index = cutoffIndex;
+                    }
+                }
+                else {
+                    // current declaration belongs to a different symbol
+                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
+                    index = cutoffIndex = result.length;
+                    lastParent = parent;
+                }
+                lastSymbol = symbol;
+                // specialized signatures always need to be placed before non-specialized signatures regardless
+                // of the cutoff position; see GH#1133
+                if (signature.hasLiteralTypes) {
+                    specializedIndex++;
+                    spliceIndex = specializedIndex;
+                    // The cutoff index always needs to be greater than or equal to the specialized signature index
+                    // in order to prevent non-specialized signatures from being added before a specialized
+                    // signature.
+                    cutoffIndex++;
+                }
+                else {
+                    spliceIndex = index;
+                }
+                result.splice(spliceIndex, 0, signature);
+            }
+        }
+        function getSpreadArgumentIndex(args) {
+            for (var i = 0; i < args.length; i++) {
+                var arg = args[i];
+                if (arg && arg.kind === 198 /* SpreadElement */) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+        function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) {
+            if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
+            var argCount; // Apparent number of arguments we will have in this call
+            var typeArguments; // Type arguments (undefined if none)
+            var callIsIncomplete; // In incomplete call we want to be lenient when we have too few arguments
+            var spreadArgIndex = -1;
+            if (ts.isJsxOpeningLikeElement(node)) {
+                // The arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement".
+                return true;
+            }
+            if (node.kind === 183 /* TaggedTemplateExpression */) {
+                var tagExpression = node;
+                // Even if the call is incomplete, we'll have a missing expression as our last argument,
+                // so we can say the count is just the arg list length
+                argCount = args.length;
+                typeArguments = undefined;
+                if (tagExpression.template.kind === 196 /* TemplateExpression */) {
+                    // If a tagged template expression lacks a tail literal, the call is incomplete.
+                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
+                    var templateExpression = tagExpression.template;
+                    var lastSpan = ts.lastOrUndefined(templateExpression.templateSpans);
+                    ts.Debug.assert(lastSpan !== undefined); // we should always have at least one span.
+                    callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated;
+                }
+                else {
+                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
+                    // then this might actually turn out to be a TemplateHead in the future;
+                    // so we consider the call to be incomplete.
+                    var templateLiteral = tagExpression.template;
+                    ts.Debug.assert(templateLiteral.kind === 13 /* NoSubstitutionTemplateLiteral */);
+                    callIsIncomplete = !!templateLiteral.isUnterminated;
+                }
+            }
+            else if (node.kind === 147 /* Decorator */) {
+                typeArguments = undefined;
+                argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
+            }
+            else {
+                var callExpression = node;
+                if (!callExpression.arguments) {
+                    // This only happens when we have something of the form: 'new C'
+                    ts.Debug.assert(callExpression.kind === 182 /* NewExpression */);
+                    return signature.minArgumentCount === 0;
+                }
+                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
+                // If we are missing the close parenthesis, the call is incomplete.
+                callIsIncomplete = callExpression.arguments.end === callExpression.end;
+                typeArguments = callExpression.typeArguments;
+                spreadArgIndex = getSpreadArgumentIndex(args);
+            }
+            // If the user supplied type arguments, but the number of type arguments does not match
+            // the declared number of type parameters, the call has an incorrect arity.
+            var numTypeParameters = ts.length(signature.typeParameters);
+            var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
+            var hasRightNumberOfTypeArgs = !typeArguments ||
+                (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
+            if (!hasRightNumberOfTypeArgs) {
+                return false;
+            }
+            // If spread arguments are present, check that they correspond to a rest parameter. If so, no
+            // further checking is necessary.
+            if (spreadArgIndex >= 0) {
+                return isRestParameterIndex(signature, spreadArgIndex) || spreadArgIndex >= signature.minArgumentCount;
+            }
+            // Too many arguments implies incorrect arity.
+            if (!signature.hasRestParameter && argCount > signature.parameters.length) {
+                return false;
+            }
+            // If the call is incomplete, we should skip the lower bound check.
+            var hasEnoughArguments = argCount >= signature.minArgumentCount;
+            return callIsIncomplete || hasEnoughArguments;
+        }
+        // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
+        function getSingleCallSignature(type) {
+            if (type.flags & 32768 /* Object */) {
+                var resolved = resolveStructuredTypeMembers(type);
+                if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
+                    resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
+                    return resolved.callSignatures[0];
+                }
+            }
+            return undefined;
+        }
+        // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
+        function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) {
+            var context = createInferenceContext(signature, 1 /* InferUnionTypes */, compareTypes);
+            forEachMatchingParameterType(contextualSignature, signature, function (source, target) {
+                // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
+                inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
+            });
+            if (!contextualMapper) {
+                inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), 8 /* ReturnType */);
+            }
+            return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJavaScriptFile(contextualSignature.declaration));
+        }
+        function inferTypeArguments(node, signature, args, excludeArgument, context) {
+            // Clear out all the inference results from the last time inferTypeArguments was called on this context
+            for (var _i = 0, _a = context.inferences; _i < _a.length; _i++) {
+                var inference = _a[_i];
+                // As an optimization, we don't have to clear (and later recompute) inferred types
+                // for type parameters that have already been fixed on the previous call to inferTypeArguments.
+                // It would be just as correct to reset all of them. But then we'd be repeating the same work
+                // for the type parameters that were fixed, namely the work done by getInferredType.
+                if (!inference.isFixed) {
+                    inference.inferredType = undefined;
+                }
+            }
+            // If a contextual type is available, infer from that type to the return type of the call expression. For
+            // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
+            // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
+            // return type of 'wrap'.
+            if (node.kind !== 147 /* Decorator */) {
+                var contextualType = getContextualType(node);
+                if (contextualType) {
+                    // We clone the contextual mapper to avoid disturbing a resolution in progress for an
+                    // outer call expression. Effectively we just want a snapshot of whatever has been
+                    // inferred for any outer call expression so far.
+                    var instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
+                    // If the contextual type is a generic function type with a single call signature, we
+                    // instantiate the type with its own type parameters and type arguments. This ensures that
+                    // the type parameters are not erased to type any during type inference such that they can
+                    // be inferred as actual types from the contextual type. For example:
+                    //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
+                    //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
+                    // Above, the type of the 'value' parameter is inferred to be 'A'.
+                    var contextualSignature = getSingleCallSignature(instantiatedType);
+                    var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
+                        getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters, ts.isInJavaScriptFile(node))) :
+                        instantiatedType;
+                    var inferenceTargetType = getReturnTypeOfSignature(signature);
+                    // Inferences made from return types have lower priority than all other inferences.
+                    inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 8 /* ReturnType */);
+                }
+            }
+            var thisType = getThisTypeOfSignature(signature);
+            if (thisType) {
+                var thisArgumentNode = getThisArgumentOfCall(node);
+                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
+                inferTypes(context.inferences, thisArgumentType, thisType);
+            }
+            // We perform two passes over the arguments. In the first pass we infer from all arguments, but use
+            // wildcards for all context sensitive function expressions.
+            var argCount = getEffectiveArgumentCount(node, args, signature);
+            for (var i = 0; i < argCount; i++) {
+                var arg = getEffectiveArgument(node, args, i);
+                // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
+                if (arg === undefined || arg.kind !== 200 /* OmittedExpression */) {
+                    var paramType = getTypeAtPosition(signature, i);
+                    var argType = getEffectiveArgumentType(node, i);
+                    // If the effective argument type is 'undefined', there is no synthetic type
+                    // for the argument. In that case, we should check the argument.
+                    if (argType === undefined) {
+                        // For context sensitive arguments we pass the identityMapper, which is a signal to treat all
+                        // context sensitive function expressions as wildcards
+                        var mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
+                        argType = checkExpressionWithContextualType(arg, paramType, mapper);
+                    }
+                    inferTypes(context.inferences, argType, paramType);
+                }
+            }
+            // In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this
+            // time treating function expressions normally (which may cause previously inferred type arguments to be fixed
+            // as we construct types for contextually typed parameters)
+            // Decorators will not have `excludeArgument`, as their arguments cannot be contextually typed.
+            // Tagged template expressions will always have `undefined` for `excludeArgument[0]`.
+            if (excludeArgument) {
+                for (var i = 0; i < argCount; i++) {
+                    // No need to check for omitted args and template expressions, their exclusion value is always undefined
+                    if (excludeArgument[i] === false) {
+                        var arg = args[i];
+                        var paramType = getTypeAtPosition(signature, i);
+                        inferTypes(context.inferences, checkExpressionWithContextualType(arg, paramType, context), paramType);
+                    }
+                }
+            }
+            return getInferredTypes(context);
+        }
+        function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) {
+            var isJavascript = ts.isInJavaScriptFile(signature.declaration);
+            var typeParameters = signature.typeParameters;
+            var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
+            var mapper;
+            for (var i = 0; i < typeArgumentNodes.length; i++) {
+                ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
+                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
+                if (!constraint)
+                    continue;
+                var errorInfo = reportErrors && headMessage && ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
+                var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
+                if (!mapper) {
+                    mapper = createTypeMapper(typeParameters, typeArgumentTypes);
+                }
+                var typeArgument = typeArgumentTypes[i];
+                if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) {
+                    return false;
+                }
+            }
+            return typeArgumentTypes;
+        }
+        /**
+         * Check if the given signature can possibly be a signature called by the JSX opening-like element.
+         * @param node a JSX opening-like element we are trying to figure its call signature
+         * @param signature a candidate signature we are trying whether it is a call signature
+         * @param relation a relationship to check parameter and argument type
+         * @param excludeArgument
+         */
+        function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation) {
+            // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true:
+            //      1. callIsIncomplete
+            //      2. attributes property has same number of properties as the parameter object type.
+            //         We can figure that out by resolving attributes property and check number of properties in the resolved type
+            // If the call has correct arity, we will then check if the argument type and parameter type is assignable
+            var callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incomplete
+            if (callIsIncomplete) {
+                return true;
+            }
+            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
+            // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
+            // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
+            // can be specified by users through attributes property.
+            var paramType = getTypeAtPosition(signature, 0);
+            var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined);
+            var argProperties = getPropertiesOfType(attributesType);
+            for (var _i = 0, argProperties_1 = argProperties; _i < argProperties_1.length; _i++) {
+                var arg = argProperties_1[_i];
+                if (!getPropertyOfType(paramType, arg.escapedName) && isUnhyphenatedJsxName(arg.escapedName)) {
+                    return false;
+                }
+            }
+            return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage);
+        }
+        function checkApplicableSignature(node, args, signature, relation, excludeArgument, reportErrors) {
+            if (ts.isJsxOpeningLikeElement(node)) {
+                return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation);
+            }
+            var thisType = getThisTypeOfSignature(signature);
+            if (thisType && thisType !== voidType && node.kind !== 182 /* NewExpression */) {
+                // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
+                // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
+                // If the expression is a new expression, then the check is skipped.
+                var thisArgumentNode = getThisArgumentOfCall(node);
+                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
+                var errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
+                var headMessage_1 = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
+                if (!checkTypeRelatedTo(thisArgumentType, getThisTypeOfSignature(signature), relation, errorNode, headMessage_1)) {
+                    return false;
+                }
+            }
+            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
+            var argCount = getEffectiveArgumentCount(node, args, signature);
+            for (var i = 0; i < argCount; i++) {
+                var arg = getEffectiveArgument(node, args, i);
+                // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
+                if (arg === undefined || arg.kind !== 200 /* OmittedExpression */) {
+                    // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
+                    var paramType = getTypeAtPosition(signature, i);
+                    // If the effective argument type is undefined, there is no synthetic type for the argument.
+                    // In that case, we should check the argument.
+                    var argType = getEffectiveArgumentType(node, i) ||
+                        checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
+                    // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
+                    // we obtain the regular type of any object literal arguments because we may not have inferred complete
+                    // parameter types yet and therefore excess property checks may yield false positives (see #17041).
+                    var checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
+                    // Use argument expression as error location when reporting errors
+                    var errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined;
+                    if (!checkTypeRelatedTo(checkArgType, paramType, relation, errorNode, headMessage)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        /**
+         * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
+         */
+        function getThisArgumentOfCall(node) {
+            if (node.kind === 181 /* CallExpression */) {
+                var callee = node.expression;
+                if (callee.kind === 179 /* PropertyAccessExpression */) {
+                    return callee.expression;
+                }
+                else if (callee.kind === 180 /* ElementAccessExpression */) {
+                    return callee.expression;
+                }
+            }
+        }
+        /**
+         * Returns the effective arguments for an expression that works like a function invocation.
+         *
+         * If 'node' is a CallExpression or a NewExpression, then its argument list is returned.
+         * If 'node' is a TaggedTemplateExpression, a new argument list is constructed from the substitution
+         *    expressions, where the first element of the list is `undefined`.
+         * If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types
+         *    will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`.
+         */
+        function getEffectiveCallArguments(node) {
+            if (node.kind === 183 /* TaggedTemplateExpression */) {
+                var template = node.template;
+                var args_4 = [undefined];
+                if (template.kind === 196 /* TemplateExpression */) {
+                    ts.forEach(template.templateSpans, function (span) {
+                        args_4.push(span.expression);
+                    });
+                }
+                return args_4;
+            }
+            else if (node.kind === 147 /* Decorator */) {
+                // For a decorator, we return undefined as we will determine
+                // the number and types of arguments for a decorator using
+                // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below.
+                return undefined;
+            }
+            else if (ts.isJsxOpeningLikeElement(node)) {
+                return node.attributes.properties.length > 0 ? [node.attributes] : ts.emptyArray;
+            }
+            else {
+                return node.arguments || ts.emptyArray;
+            }
+        }
+        /**
+         * Returns the effective argument count for a node that works like a function invocation.
+         * If 'node' is a Decorator, the number of arguments is derived from the decoration
+         *    target and the signature:
+         *    If 'node.target' is a class declaration or class expression, the effective argument
+         *       count is 1.
+         *    If 'node.target' is a parameter declaration, the effective argument count is 3.
+         *    If 'node.target' is a property declaration, the effective argument count is 2.
+         *    If 'node.target' is a method or accessor declaration, the effective argument count
+         *       is 3, although it can be 2 if the signature only accepts two arguments, allowing
+         *       us to match a property decorator.
+         * Otherwise, the argument count is the length of the 'args' array.
+         */
+        function getEffectiveArgumentCount(node, args, signature) {
+            if (node.kind === 147 /* Decorator */) {
+                switch (node.parent.kind) {
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                        // A class decorator will have one argument (see `ClassDecorator` in core.d.ts)
+                        return 1;
+                    case 149 /* PropertyDeclaration */:
+                        // A property declaration decorator will have two arguments (see
+                        // `PropertyDecorator` in core.d.ts)
+                        return 2;
+                    case 151 /* MethodDeclaration */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        // A method or accessor declaration decorator will have two or three arguments (see
+                        // `PropertyDecorator` and `MethodDecorator` in core.d.ts)
+                        // If we are emitting decorators for ES3, we will only pass two arguments.
+                        if (languageVersion === 0 /* ES3 */) {
+                            return 2;
+                        }
+                        // If the method decorator signature only accepts a target and a key, we will only
+                        // type check those arguments.
+                        return signature.parameters.length >= 3 ? 3 : 2;
+                    case 146 /* Parameter */:
+                        // A parameter declaration decorator will have three arguments (see
+                        // `ParameterDecorator` in core.d.ts)
+                        return 3;
+                }
+            }
+            else {
+                return args.length;
+            }
+        }
+        /**
+         * Returns the effective type of the first argument to a decorator.
+         * If 'node' is a class declaration or class expression, the effective argument type
+         *    is the type of the static side of the class.
+         * If 'node' is a parameter declaration, the effective argument type is either the type
+         *    of the static or instance side of the class for the parameter's parent method,
+         *    depending on whether the method is declared static.
+         *    For a constructor, the type is always the type of the static side of the class.
+         * If 'node' is a property, method, or accessor declaration, the effective argument
+         *    type is the type of the static or instance side of the parent class for class
+         *    element, depending on whether the element is declared static.
+         */
+        function getEffectiveDecoratorFirstArgumentType(node) {
+            // The first argument to a decorator is its `target`.
+            if (node.kind === 229 /* ClassDeclaration */) {
+                // For a class decorator, the `target` is the type of the class (e.g. the
+                // "static" or "constructor" side of the class)
+                var classSymbol = getSymbolOfNode(node);
+                return getTypeOfSymbol(classSymbol);
+            }
+            if (node.kind === 146 /* Parameter */) {
+                // For a parameter decorator, the `target` is the parent type of the
+                // parameter's containing method.
+                node = node.parent;
+                if (node.kind === 152 /* Constructor */) {
+                    var classSymbol = getSymbolOfNode(node);
+                    return getTypeOfSymbol(classSymbol);
+                }
+            }
+            if (node.kind === 149 /* PropertyDeclaration */ ||
+                node.kind === 151 /* MethodDeclaration */ ||
+                node.kind === 153 /* GetAccessor */ ||
+                node.kind === 154 /* SetAccessor */) {
+                // For a property or method decorator, the `target` is the
+                // "static"-side type of the parent of the member if the member is
+                // declared "static"; otherwise, it is the "instance"-side type of the
+                // parent of the member.
+                return getParentTypeOfClassElement(node);
+            }
+            ts.Debug.fail("Unsupported decorator target.");
+            return unknownType;
+        }
+        /**
+         * Returns the effective type for the second argument to a decorator.
+         * If 'node' is a parameter, its effective argument type is one of the following:
+         *    If 'node.parent' is a constructor, the effective argument type is 'any', as we
+         *       will emit `undefined`.
+         *    If 'node.parent' is a member with an identifier, numeric, or string literal name,
+         *       the effective argument type will be a string literal type for the member name.
+         *    If 'node.parent' is a computed property name, the effective argument type will
+         *       either be a symbol type or the string type.
+         * If 'node' is a member with an identifier, numeric, or string literal name, the
+         *    effective argument type will be a string literal type for the member name.
+         * If 'node' is a computed property name, the effective argument type will either
+         *    be a symbol type or the string type.
+         * A class decorator does not have a second argument type.
+         */
+        function getEffectiveDecoratorSecondArgumentType(node) {
+            // The second argument to a decorator is its `propertyKey`
+            if (node.kind === 229 /* ClassDeclaration */) {
+                ts.Debug.fail("Class decorators should not have a second synthetic argument.");
+                return unknownType;
+            }
+            if (node.kind === 146 /* Parameter */) {
+                node = node.parent;
+                if (node.kind === 152 /* Constructor */) {
+                    // For a constructor parameter decorator, the `propertyKey` will be `undefined`.
+                    return anyType;
+                }
+                // For a non-constructor parameter decorator, the `propertyKey` will be either
+                // a string or a symbol, based on the name of the parameter's containing method.
+            }
+            if (node.kind === 149 /* PropertyDeclaration */ ||
+                node.kind === 151 /* MethodDeclaration */ ||
+                node.kind === 153 /* GetAccessor */ ||
+                node.kind === 154 /* SetAccessor */) {
+                // The `propertyKey` for a property or method decorator will be a
+                // string literal type if the member name is an identifier, number, or string;
+                // otherwise, if the member name is a computed property name it will
+                // be either string or symbol.
+                var element = node;
+                switch (element.name.kind) {
+                    case 71 /* Identifier */:
+                        return getLiteralType(ts.idText(element.name));
+                    case 8 /* NumericLiteral */:
+                    case 9 /* StringLiteral */:
+                        return getLiteralType(element.name.text);
+                    case 144 /* ComputedPropertyName */:
+                        var nameType = checkComputedPropertyName(element.name);
+                        if (isTypeAssignableToKind(nameType, 512 /* ESSymbol */)) {
+                            return nameType;
+                        }
+                        else {
+                            return stringType;
+                        }
+                    default:
+                        ts.Debug.fail("Unsupported property name.");
+                        return unknownType;
+                }
+            }
+            ts.Debug.fail("Unsupported decorator target.");
+            return unknownType;
+        }
+        /**
+         * Returns the effective argument type for the third argument to a decorator.
+         * If 'node' is a parameter, the effective argument type is the number type.
+         * If 'node' is a method or accessor, the effective argument type is a
+         *    `TypedPropertyDescriptor<T>` instantiated with the type of the member.
+         * Class and property decorators do not have a third effective argument.
+         */
+        function getEffectiveDecoratorThirdArgumentType(node) {
+            // The third argument to a decorator is either its `descriptor` for a method decorator
+            // or its `parameterIndex` for a parameter decorator
+            if (node.kind === 229 /* ClassDeclaration */) {
+                ts.Debug.fail("Class decorators should not have a third synthetic argument.");
+                return unknownType;
+            }
+            if (node.kind === 146 /* Parameter */) {
+                // The `parameterIndex` for a parameter decorator is always a number
+                return numberType;
+            }
+            if (node.kind === 149 /* PropertyDeclaration */) {
+                ts.Debug.fail("Property decorators should not have a third synthetic argument.");
+                return unknownType;
+            }
+            if (node.kind === 151 /* MethodDeclaration */ ||
+                node.kind === 153 /* GetAccessor */ ||
+                node.kind === 154 /* SetAccessor */) {
+                // The `descriptor` for a method decorator will be a `TypedPropertyDescriptor<T>`
+                // for the type of the member.
+                var propertyType = getTypeOfNode(node);
+                return createTypedPropertyDescriptorType(propertyType);
+            }
+            ts.Debug.fail("Unsupported decorator target.");
+            return unknownType;
+        }
+        /**
+         * Returns the effective argument type for the provided argument to a decorator.
+         */
+        function getEffectiveDecoratorArgumentType(node, argIndex) {
+            if (argIndex === 0) {
+                return getEffectiveDecoratorFirstArgumentType(node.parent);
+            }
+            else if (argIndex === 1) {
+                return getEffectiveDecoratorSecondArgumentType(node.parent);
+            }
+            else if (argIndex === 2) {
+                return getEffectiveDecoratorThirdArgumentType(node.parent);
+            }
+            ts.Debug.fail("Decorators should not have a fourth synthetic argument.");
+            return unknownType;
+        }
+        /**
+         * Gets the effective argument type for an argument in a call expression.
+         */
+        function getEffectiveArgumentType(node, argIndex) {
+            // Decorators provide special arguments, a tagged template expression provides
+            // a special first argument, and string literals get string literal types
+            // unless we're reporting errors
+            if (node.kind === 147 /* Decorator */) {
+                return getEffectiveDecoratorArgumentType(node, argIndex);
+            }
+            else if (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */) {
+                return getGlobalTemplateStringsArrayType();
+            }
+            // This is not a synthetic argument, so we return 'undefined'
+            // to signal that the caller needs to check the argument.
+            return undefined;
+        }
+        /**
+         * Gets the effective argument expression for an argument in a call expression.
+         */
+        function getEffectiveArgument(node, args, argIndex) {
+            // For a decorator or the first argument of a tagged template expression we return undefined.
+            if (node.kind === 147 /* Decorator */ ||
+                (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */)) {
+                return undefined;
+            }
+            return args[argIndex];
+        }
+        /**
+         * Gets the error node to use when reporting errors for an effective argument.
+         */
+        function getEffectiveArgumentErrorNode(node, argIndex, arg) {
+            if (node.kind === 147 /* Decorator */) {
+                // For a decorator, we use the expression of the decorator for error reporting.
+                return node.expression;
+            }
+            else if (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */) {
+                // For a the first argument of a tagged template expression, we use the template of the tag for error reporting.
+                return node.template;
+            }
+            else {
+                return arg;
+            }
+        }
+        function resolveCall(node, signatures, candidatesOutArray, fallbackError) {
+            var isTaggedTemplate = node.kind === 183 /* TaggedTemplateExpression */;
+            var isDecorator = node.kind === 147 /* Decorator */;
+            var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node);
+            var typeArguments;
+            if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
+                typeArguments = node.typeArguments;
+                // We already perform checking on the type arguments on the class declaration itself.
+                if (node.expression.kind !== 97 /* SuperKeyword */) {
+                    ts.forEach(typeArguments, checkSourceElement);
+                }
+            }
+            var candidates = candidatesOutArray || [];
+            // reorderCandidates fills up the candidates array directly
+            reorderCandidates(signatures, candidates);
+            if (!candidates.length) {
+                diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures));
+                return resolveErrorCall(node);
+            }
+            var args = getEffectiveCallArguments(node);
+            // The following applies to any value of 'excludeArgument[i]':
+            //    - true:      the argument at 'i' is susceptible to a one-time permanent contextual typing.
+            //    - undefined: the argument at 'i' is *not* susceptible to permanent contextual typing.
+            //    - false:     the argument at 'i' *was* and *has been* permanently contextually typed.
+            //
+            // The idea is that we will perform type argument inference & assignability checking once
+            // without using the susceptible parameters that are functions, and once more for each of those
+            // parameters, contextually typing each as we go along.
+            //
+            // For a tagged template, then the first argument be 'undefined' if necessary
+            // because it represents a TemplateStringsArray.
+            //
+            // For a decorator, no arguments are susceptible to contextual typing due to the fact
+            // decorators are applied to a declaration by the emitter, and not to an expression.
+            var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
+            var excludeArgument;
+            var excludeCount = 0;
+            if (!isDecorator && !isSingleNonGenericCandidate) {
+                // We do not need to call `getEffectiveArgumentCount` here as it only
+                // applies when calculating the number of arguments for a decorator.
+                for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) {
+                    if (isContextSensitive(args[i])) {
+                        if (!excludeArgument) {
+                            excludeArgument = new Array(args.length);
+                        }
+                        excludeArgument[i] = true;
+                        excludeCount++;
+                    }
+                }
+            }
+            // The following variables are captured and modified by calls to chooseOverload.
+            // If overload resolution or type argument inference fails, we want to report the
+            // best error possible. The best error is one which says that an argument was not
+            // assignable to a parameter. This implies that everything else about the overload
+            // was fine. So if there is any overload that is only incorrect because of an
+            // argument, we will report an error on that one.
+            //
+            //     function foo(s: string): void;
+            //     function foo(n: number): void; // Report argument error on this overload
+            //     function foo(): void;
+            //     foo(true);
+            //
+            // If none of the overloads even made it that far, there are two possibilities.
+            // There was a problem with type arguments for some overload, in which case
+            // report an error on that. Or none of the overloads even had correct arity,
+            // in which case give an arity error.
+            //
+            //     function foo<T extends string>(x: T): void; // Report type argument error
+            //     function foo(): void;
+            //     foo<number>(0);
+            //
+            var candidateForArgumentError;
+            var candidateForTypeArgumentError;
+            var result;
+            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
+            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
+            var signatureHelpTrailingComma = candidatesOutArray && node.kind === 181 /* CallExpression */ && node.arguments.hasTrailingComma;
+            // Section 4.12.1:
+            // if the candidate list contains one or more signatures for which the type of each argument
+            // expression is a subtype of each corresponding parameter type, the return type of the first
+            // of those signatures becomes the return type of the function call.
+            // Otherwise, the return type of the first signature in the candidate list becomes the return
+            // type of the function call.
+            //
+            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
+            // is just important for choosing the best signature. So in the case where there is only one
+            // signature, the subtype pass is useless. So skipping it is an optimization.
+            if (candidates.length > 1) {
+                result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
+            }
+            if (!result) {
+                result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
+            }
+            if (result) {
+                return result;
+            }
+            // No signatures were applicable. Now report errors based on the last applicable signature with
+            // no arguments excluded from assignability checks.
+            // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
+            // skip the checkApplicableSignature check.
+            if (candidateForArgumentError) {
+                if (isJsxOpeningOrSelfClosingElement) {
+                    // We do not report any error here because any error will be handled in "resolveCustomJsxElementAttributesType".
+                    return candidateForArgumentError;
+                }
+                // excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
+                // The importance of excludeArgument is to prevent us from typing function expression parameters
+                // in arguments too early. If possible, we'd like to only type them once we know the correct
+                // overload. However, this matters for the case where the call is correct. When the call is
+                // an error, we don't need to exclude any arguments, although it would cause no harm to do so.
+                checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
+            }
+            else if (candidateForTypeArgumentError) {
+                checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError);
+            }
+            else if (typeArguments && ts.every(signatures, function (sig) { return ts.length(sig.typeParameters) !== typeArguments.length; })) {
+                var min = Number.POSITIVE_INFINITY;
+                var max = Number.NEGATIVE_INFINITY;
+                for (var _i = 0, signatures_5 = signatures; _i < signatures_5.length; _i++) {
+                    var sig = signatures_5[_i];
+                    min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
+                    max = Math.max(max, ts.length(sig.typeParameters));
+                }
+                var paramCount = min < max ? min + "-" + max : min;
+                diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
+            }
+            else if (args) {
+                var min = Number.POSITIVE_INFINITY;
+                var max = Number.NEGATIVE_INFINITY;
+                for (var _a = 0, signatures_6 = signatures; _a < signatures_6.length; _a++) {
+                    var sig = signatures_6[_a];
+                    min = Math.min(min, sig.minArgumentCount);
+                    max = Math.max(max, sig.parameters.length);
+                }
+                var hasRestParameter_1 = ts.some(signatures, function (sig) { return sig.hasRestParameter; });
+                var hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
+                var paramCount = hasRestParameter_1 ? min :
+                    min < max ? min + "-" + max :
+                        min;
+                var argCount = args.length - (hasSpreadArgument ? 1 : 0);
+                var error_1 = hasRestParameter_1 && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_a_minimum_of_1 :
+                    hasRestParameter_1 ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 :
+                        hasSpreadArgument ? ts.Diagnostics.Expected_0_arguments_but_got_a_minimum_of_1 :
+                            ts.Diagnostics.Expected_0_arguments_but_got_1;
+                diagnostics.add(ts.createDiagnosticForNode(node, error_1, paramCount, argCount));
+            }
+            else if (fallbackError) {
+                diagnostics.add(ts.createDiagnosticForNode(node, fallbackError));
+            }
+            // No signature was applicable. We have already reported the errors for the invalid signature.
+            // If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
+            // Pick the longest signature. This way we can get a contextual type for cases like:
+            //     declare function f(a: { xa: number; xb: number; }, b: number);
+            //     f({ |
+            // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
+            //     declare function f<T>(k: keyof T);
+            //     f<Foo>("
+            if (!produceDiagnostics) {
+                ts.Debug.assert(candidates.length > 0); // Else would have exited above.
+                var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
+                var candidate = candidates[bestIndex];
+                var typeParameters = candidate.typeParameters;
+                if (typeParameters && callLikeExpressionMayHaveTypeArguments(node) && node.typeArguments) {
+                    var typeArguments_1 = node.typeArguments.map(getTypeOfNode);
+                    while (typeArguments_1.length > typeParameters.length) {
+                        typeArguments_1.pop();
+                    }
+                    while (typeArguments_1.length < typeParameters.length) {
+                        typeArguments_1.push(getDefaultTypeArgumentType(ts.isInJavaScriptFile(node)));
+                    }
+                    var instantiated = createSignatureInstantiation(candidate, typeArguments_1);
+                    candidates[bestIndex] = instantiated;
+                    return instantiated;
+                }
+                return candidate;
+            }
+            return resolveErrorCall(node);
+            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
+                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
+                candidateForArgumentError = undefined;
+                candidateForTypeArgumentError = undefined;
+                if (isSingleNonGenericCandidate) {
+                    var candidate = candidates[0];
+                    if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
+                        return undefined;
+                    }
+                    if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
+                        candidateForArgumentError = candidate;
+                        return undefined;
+                    }
+                    return candidate;
+                }
+                for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
+                    var originalCandidate = candidates[candidateIndex];
+                    if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
+                        continue;
+                    }
+                    var candidate = void 0;
+                    var inferenceContext = originalCandidate.typeParameters ?
+                        createInferenceContext(originalCandidate, /*flags*/ ts.isInJavaScriptFile(node) ? 4 /* AnyDefault */ : 0) :
+                        undefined;
+                    while (true) {
+                        candidate = originalCandidate;
+                        if (candidate.typeParameters) {
+                            var typeArgumentTypes = void 0;
+                            if (typeArguments) {
+                                var typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
+                                if (typeArgumentResult) {
+                                    typeArgumentTypes = typeArgumentResult;
+                                }
+                                else {
+                                    candidateForTypeArgumentError = originalCandidate;
+                                    break;
+                                }
+                            }
+                            else {
+                                typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
+                            }
+                            var isJavascript = ts.isInJavaScriptFile(candidate.declaration);
+                            candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript);
+                        }
+                        if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
+                            candidateForArgumentError = candidate;
+                            break;
+                        }
+                        if (excludeCount === 0) {
+                            candidates[candidateIndex] = candidate;
+                            return candidate;
+                        }
+                        excludeCount--;
+                        if (excludeCount > 0) {
+                            excludeArgument[ts.indexOf(excludeArgument, /*value*/ true)] = false;
+                        }
+                        else {
+                            excludeArgument = undefined;
+                        }
+                    }
+                }
+                return undefined;
+            }
+        }
+        function getLongestCandidateIndex(candidates, argsCount) {
+            var maxParamsIndex = -1;
+            var maxParams = -1;
+            for (var i = 0; i < candidates.length; i++) {
+                var candidate = candidates[i];
+                if (candidate.hasRestParameter || candidate.parameters.length >= argsCount) {
+                    return i;
+                }
+                if (candidate.parameters.length > maxParams) {
+                    maxParams = candidate.parameters.length;
+                    maxParamsIndex = i;
+                }
+            }
+            return maxParamsIndex;
+        }
+        function resolveCallExpression(node, candidatesOutArray) {
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                var superType = checkSuperExpression(node.expression);
+                if (superType !== unknownType) {
+                    // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
+                    // with the type arguments specified in the extends clause.
+                    var baseTypeNode = ts.getClassExtendsHeritageClauseElement(ts.getContainingClass(node));
+                    if (baseTypeNode) {
+                        var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
+                        return resolveCall(node, baseConstructors, candidatesOutArray);
+                    }
+                }
+                return resolveUntypedCall(node);
+            }
+            var funcType = checkNonNullExpression(node.expression);
+            if (funcType === silentNeverType) {
+                return silentNeverSignature;
+            }
+            var apparentType = getApparentType(funcType);
+            if (apparentType === unknownType) {
+                // Another error has already been reported
+                return resolveErrorCall(node);
+            }
+            // Technically, this signatures list may be incomplete. We are taking the apparent type,
+            // but we are not including call signatures that may have been added to the Object or
+            // Function interface, since they have none by default. This is a bit of a leap of faith
+            // that the user will not add any.
+            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
+            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
+            // TS 1.0 Spec: 4.12
+            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
+            // types are provided for the argument expressions, and the result is always of type Any.
+            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
+                // The unknownType indicates that an error already occurred (and was reported).  No
+                // need to report another error in this case.
+                if (funcType !== unknownType && node.typeArguments) {
+                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
+                }
+                return resolveUntypedCall(node);
+            }
+            // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
+            // TypeScript employs overload resolution in typed function calls in order to support functions
+            // with multiple call signatures.
+            if (!callSignatures.length) {
+                if (constructSignatures.length) {
+                    error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
+                }
+                else {
+                    error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
+                }
+                return resolveErrorCall(node);
+            }
+            return resolveCall(node, callSignatures, candidatesOutArray);
+        }
+        /**
+         * TS 1.0 spec: 4.12
+         * If FuncExpr is of type Any, or of an object type that has no call or construct signatures
+         * but is a subtype of the Function interface, the call is an untyped function call.
+         */
+        function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) {
+            if (isTypeAny(funcType)) {
+                return true;
+            }
+            if (isTypeAny(apparentFuncType) && funcType.flags & 16384 /* TypeParameter */) {
+                return true;
+            }
+            if (!numCallSignatures && !numConstructSignatures) {
+                // We exclude union types because we may have a union of function types that happen to have
+                // no common signatures.
+                if (funcType.flags & 65536 /* Union */) {
+                    return false;
+                }
+                return isTypeAssignableTo(funcType, globalFunctionType);
+            }
+            return false;
+        }
+        function resolveNewExpression(node, candidatesOutArray) {
+            if (node.arguments && languageVersion < 1 /* ES5 */) {
+                var spreadIndex = getSpreadArgumentIndex(node.arguments);
+                if (spreadIndex >= 0) {
+                    error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
+                }
+            }
+            var expressionType = checkNonNullExpression(node.expression);
+            if (expressionType === silentNeverType) {
+                return silentNeverSignature;
+            }
+            // If expressionType's apparent type(section 3.8.1) is an object type with one or
+            // more construct signatures, the expression is processed in the same manner as a
+            // function call, but using the construct signatures as the initial set of candidate
+            // signatures for overload resolution. The result type of the function call becomes
+            // the result type of the operation.
+            expressionType = getApparentType(expressionType);
+            if (expressionType === unknownType) {
+                // Another error has already been reported
+                return resolveErrorCall(node);
+            }
+            // TS 1.0 spec: 4.11
+            // If expressionType is of type Any, Args can be any argument
+            // list and the result of the operation is of type Any.
+            if (isTypeAny(expressionType)) {
+                if (node.typeArguments) {
+                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
+                }
+                return resolveUntypedCall(node);
+            }
+            // Technically, this signatures list may be incomplete. We are taking the apparent type,
+            // but we are not including construct signatures that may have been added to the Object or
+            // Function interface, since they have none by default. This is a bit of a leap of faith
+            // that the user will not add any.
+            var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
+            if (constructSignatures.length) {
+                if (!isConstructorAccessible(node, constructSignatures[0])) {
+                    return resolveErrorCall(node);
+                }
+                // If the expression is a class of abstract type, then it cannot be instantiated.
+                // Note, only class declarations can be declared abstract.
+                // In the case of a merged class-module or class-interface declaration,
+                // only the class declaration node will have the Abstract flag set.
+                var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
+                if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) {
+                    error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl)));
+                    return resolveErrorCall(node);
+                }
+                return resolveCall(node, constructSignatures, candidatesOutArray);
+            }
+            // If expressionType's apparent type is an object type with no construct signatures but
+            // one or more call signatures, the expression is processed as a function call. A compile-time
+            // error occurs if the result of the function call is not Void. The type of the result of the
+            // operation is Any. It is an error to have a Void this type.
+            var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
+            if (callSignatures.length) {
+                var signature = resolveCall(node, callSignatures, candidatesOutArray);
+                if (!isJavaScriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
+                    error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
+                }
+                if (getThisTypeOfSignature(signature) === voidType) {
+                    error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
+                }
+                return signature;
+            }
+            error(node, ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature);
+            return resolveErrorCall(node);
+        }
+        function isConstructorAccessible(node, signature) {
+            if (!signature || !signature.declaration) {
+                return true;
+            }
+            var declaration = signature.declaration;
+            var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */);
+            // Public constructor is accessible.
+            if (!modifiers) {
+                return true;
+            }
+            var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
+            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
+            // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
+            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
+                var containingClass = ts.getContainingClass(node);
+                if (containingClass) {
+                    var containingType = getTypeOfNode(containingClass);
+                    var baseTypes = getBaseTypes(containingType);
+                    while (baseTypes.length) {
+                        var baseType = baseTypes[0];
+                        if (modifiers & 16 /* Protected */ &&
+                            baseType.symbol === declaration.parent.symbol) {
+                            return true;
+                        }
+                        baseTypes = getBaseTypes(baseType);
+                    }
+                }
+                if (modifiers & 8 /* Private */) {
+                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
+                }
+                if (modifiers & 16 /* Protected */) {
+                    error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
+                }
+                return false;
+            }
+            return true;
+        }
+        function resolveTaggedTemplateExpression(node, candidatesOutArray) {
+            var tagType = checkExpression(node.tag);
+            var apparentType = getApparentType(tagType);
+            if (apparentType === unknownType) {
+                // Another error has already been reported
+                return resolveErrorCall(node);
+            }
+            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
+            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
+            if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
+                return resolveUntypedCall(node);
+            }
+            if (!callSignatures.length) {
+                error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
+                return resolveErrorCall(node);
+            }
+            return resolveCall(node, callSignatures, candidatesOutArray);
+        }
+        /**
+         * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
+         */
+        function getDiagnosticHeadMessageForDecoratorResolution(node) {
+            switch (node.parent.kind) {
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
+                case 146 /* Parameter */:
+                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
+                case 149 /* PropertyDeclaration */:
+                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
+            }
+        }
+        /**
+         * Resolves a decorator as if it were a call expression.
+         */
+        function resolveDecorator(node, candidatesOutArray) {
+            var funcType = checkExpression(node.expression);
+            var apparentType = getApparentType(funcType);
+            if (apparentType === unknownType) {
+                return resolveErrorCall(node);
+            }
+            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
+            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
+            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
+                return resolveUntypedCall(node);
+            }
+            if (isPotentiallyUncalledDecorator(node, callSignatures)) {
+                var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false);
+                error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
+                return resolveErrorCall(node);
+            }
+            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
+            if (!callSignatures.length) {
+                var errorInfo = void 0;
+                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
+                errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
+                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo));
+                return resolveErrorCall(node);
+            }
+            return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
+        }
+        /**
+         * Sometimes, we have a decorator that could accept zero arguments,
+         * but is receiving too many arguments as part of the decorator invocation.
+         * In those cases, a user may have meant to *call* the expression before using it as a decorator.
+         */
+        function isPotentiallyUncalledDecorator(decorator, signatures) {
+            return signatures.length && ts.every(signatures, function (signature) {
+                return signature.minArgumentCount === 0 &&
+                    !signature.hasRestParameter &&
+                    signature.parameters.length < getEffectiveArgumentCount(decorator, /*args*/ undefined, signature);
+            });
+        }
+        /**
+         * This function is similar to getResolvedSignature but is exclusively for trying to resolve JSX stateless-function component.
+         * The main reason we have to use this function instead of getResolvedSignature because, the caller of this function will already check the type of openingLikeElement's tagName
+         * and pass the type as elementType. The elementType can not be a union (as such case should be handled by the caller of this function)
+         * Note: at this point, we are still not sure whether the opening-like element is a stateless function component or not.
+         * @param openingLikeElement an opening-like JSX element to try to resolve as JSX stateless function
+         * @param elementType an element type of the opneing-like element by checking opening-like element's tagname.
+         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
+         *                           the function will fill it up with appropriate candidate signatures
+         */
+        function getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray) {
+            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
+            return resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray);
+        }
+        /**
+         * Try treating a given opening-like element as stateless function component and resolve a tagName to a function signature.
+         * @param openingLikeElement an JSX opening-like element we want to try resolve its stateless function if possible
+         * @param elementType a type of the opening-like JSX element, a result of resolving tagName in opening-like element.
+         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
+         *                           the function will fill it up with appropriate candidate signatures
+         * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions.
+         *         otherwise return undefined if tag-name of the opening-like element doesn't have call signatures
+         */
+        function resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray) {
+            // If this function is called from language service, elementType can be a union type. This is not possible if the function is called from compiler (see: resolveCustomJsxElementAttributesType)
+            if (elementType.flags & 65536 /* Union */) {
+                var types = elementType.types;
+                var result = void 0;
+                for (var _i = 0, types_17 = types; _i < types_17.length; _i++) {
+                    var type = types_17[_i];
+                    result = result || resolveStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray);
+                }
+                return result;
+            }
+            var callSignatures = elementType && getSignaturesOfType(elementType, 0 /* Call */);
+            if (callSignatures && callSignatures.length > 0) {
+                return resolveCall(openingLikeElement, callSignatures, candidatesOutArray);
+            }
+            return undefined;
+        }
+        function resolveSignature(node, candidatesOutArray) {
+            switch (node.kind) {
+                case 181 /* CallExpression */:
+                    return resolveCallExpression(node, candidatesOutArray);
+                case 182 /* NewExpression */:
+                    return resolveNewExpression(node, candidatesOutArray);
+                case 183 /* TaggedTemplateExpression */:
+                    return resolveTaggedTemplateExpression(node, candidatesOutArray);
+                case 147 /* Decorator */:
+                    return resolveDecorator(node, candidatesOutArray);
+                case 251 /* JsxOpeningElement */:
+                case 250 /* JsxSelfClosingElement */:
+                    // This code-path is called by language service
+                    return resolveStatelessJsxOpeningLikeElement(node, checkExpression(node.tagName), candidatesOutArray) || unknownSignature;
+            }
+            ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
+        }
+        /**
+         * Resolve a signature of a given call-like expression.
+         * @param node a call-like expression to try resolve a signature for
+         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
+         *                           the function will fill it up with appropriate candidate signatures
+         * @return a signature of the call-like expression or undefined if one can't be found
+         */
+        function getResolvedSignature(node, candidatesOutArray) {
+            var links = getNodeLinks(node);
+            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
+            // However, it is possible that either candidatesOutArray was not passed in the first time,
+            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
+            // to correctly fill the candidatesOutArray.
+            var cached = links.resolvedSignature;
+            if (cached && cached !== resolvingSignature && !candidatesOutArray) {
+                return cached;
+            }
+            links.resolvedSignature = resolvingSignature;
+            var result = resolveSignature(node, candidatesOutArray);
+            // If signature resolution originated in control flow type analysis (for example to compute the
+            // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
+            // types from the control flow analysis.
+            links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
+            return result;
+        }
+        /**
+         * Indicates whether a declaration can be treated as a constructor in a JavaScript
+         * file.
+         */
+        function isJavaScriptConstructor(node) {
+            if (node && ts.isInJavaScriptFile(node)) {
+                // If the node has a @class tag, treat it like a constructor.
+                if (ts.getJSDocClassTag(node))
+                    return true;
+                // If the symbol of the node has members, treat it like a constructor.
+                var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) :
+                    ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
+                        undefined;
+                return symbol && symbol.members !== undefined;
+            }
+            return false;
+        }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3 /* Variable */) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
+        function getInferredClassType(symbol) {
+            var links = getSymbolLinks(symbol);
+            if (!links.inferredClassType) {
+                links.inferredClassType = createAnonymousType(symbol, symbol.members || emptySymbols, ts.emptyArray, ts.emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
+            }
+            return links.inferredClassType;
+        }
+        function isInferredClassType(type) {
+            return type.symbol
+                && getObjectFlags(type) & 16 /* Anonymous */
+                && getSymbolLinks(type.symbol).inferredClassType === type;
+        }
+        /**
+         * Syntactically and semantically checks a call or new expression.
+         * @param node The call/new expression to be checked.
+         * @returns On success, the expression's signature's return type. On failure, anyType.
+         */
+        function checkCallExpression(node) {
+            // Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
+            checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node.arguments);
+            var signature = getResolvedSignature(node);
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                return voidType;
+            }
+            if (node.kind === 182 /* NewExpression */) {
+                var declaration = signature.declaration;
+                if (declaration &&
+                    declaration.kind !== 152 /* Constructor */ &&
+                    declaration.kind !== 156 /* ConstructSignature */ &&
+                    declaration.kind !== 161 /* ConstructorType */ &&
+                    !ts.isJSDocConstructSignature(declaration)) {
+                    // When resolved signature is a call signature (and not a construct signature) the result type is any, unless
+                    // the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
+                    // in a JS file
+                    // Note:JS inferred classes might come from a variable declaration instead of a function declaration.
+                    // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
+                    var funcSymbol = checkExpression(node.expression).symbol;
+                    if (!funcSymbol && node.expression.kind === 71 /* Identifier */) {
+                        funcSymbol = getResolvedSymbol(node.expression);
+                    }
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
+                    }
+                    if (noImplicitAny) {
+                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
+                    }
+                    return anyType;
+                }
+            }
+            // In JavaScript files, calls to any identifier 'require' are treated as external module imports
+            if (ts.isInJavaScriptFile(node) && isCommonJsRequire(node)) {
+                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+            }
+            return getReturnTypeOfSignature(signature);
+        }
+        function checkImportCallExpression(node) {
+            // Check grammar of dynamic import
+            checkGrammarArguments(node.arguments) || checkGrammarImportCallExpression(node);
+            if (node.arguments.length === 0) {
+                return createPromiseReturnType(node, anyType);
+            }
+            var specifier = node.arguments[0];
+            var specifierType = checkExpressionCached(specifier);
+            // Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion
+            for (var i = 1; i < node.arguments.length; ++i) {
+                checkExpressionCached(node.arguments[i]);
+            }
+            if (specifierType.flags & 2048 /* Undefined */ || specifierType.flags & 4096 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) {
+                error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
+            }
+            // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
+            var moduleSymbol = resolveExternalModuleName(node, specifier);
+            if (moduleSymbol) {
+                var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
+                if (esModuleSymbol) {
+                    return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol));
+                }
+            }
+            return createPromiseReturnType(node, anyType);
+        }
+        function getTypeWithSyntheticDefaultImportType(type, symbol) {
+            if (allowSyntheticDefaultImports && type && type !== unknownType) {
+                var synthType = type;
+                if (!synthType.syntheticType) {
+                    if (!getPropertyOfType(type, "default" /* Default */)) {
+                        var memberTable = ts.createSymbolTable();
+                        var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */);
+                        newSymbol.target = resolveSymbol(symbol);
+                        memberTable.set("default" /* Default */, newSymbol);
+                        var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
+                        var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
+                        anonymousSymbol.type = defaultContainingObject;
+                        synthType.syntheticType = getIntersectionType([type, defaultContainingObject]);
+                    }
+                    else {
+                        synthType.syntheticType = type;
+                    }
+                }
+                return synthType.syntheticType;
+            }
+            return type;
+        }
+        function isCommonJsRequire(node) {
+            if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
+                return false;
+            }
+            // Make sure require is not a local function
+            if (!ts.isIdentifier(node.expression))
+                throw ts.Debug.fail();
+            var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
+            if (!resolvedRequire) {
+                // project does not contain symbol named 'require' - assume commonjs require
+                return true;
+            }
+            // project includes symbol named 'require' - make sure that it it ambient and local non-alias
+            if (resolvedRequire.flags & 2097152 /* Alias */) {
+                return false;
+            }
+            var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */
+                ? 228 /* FunctionDeclaration */
+                : resolvedRequire.flags & 3 /* Variable */
+                    ? 226 /* VariableDeclaration */
+                    : 0 /* Unknown */;
+            if (targetDeclarationKind !== 0 /* Unknown */) {
+                var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
+                // function/variable declaration should be ambient
+                return ts.isInAmbientContext(decl);
+            }
+            return false;
+        }
+        function checkTaggedTemplateExpression(node) {
+            if (languageVersion < 2 /* ES2015 */) {
+                checkExternalEmitHelpers(node, 65536 /* MakeTemplateObject */);
+            }
+            return getReturnTypeOfSignature(getResolvedSignature(node));
+        }
+        function checkAssertion(node) {
+            return checkAssertionWorker(node, node.type, node.expression);
+        }
+        function checkAssertionWorker(errNode, type, expression, checkMode) {
+            var exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression, checkMode)));
+            checkSourceElement(type);
+            var targetType = getTypeFromTypeNode(type);
+            if (produceDiagnostics && targetType !== unknownType) {
+                var widenedType = getWidenedType(exprType);
+                if (!isTypeComparableTo(targetType, widenedType)) {
+                    checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Type_0_cannot_be_converted_to_type_1);
+                }
+            }
+            return targetType;
+        }
+        function checkNonNullAssertion(node) {
+            return getNonNullableType(checkExpression(node.expression));
+        }
+        function checkMetaProperty(node) {
+            checkGrammarMetaProperty(node);
+            var container = ts.getNewTargetContainer(node);
+            if (!container) {
+                error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
+                return unknownType;
+            }
+            else if (container.kind === 152 /* Constructor */) {
+                var symbol = getSymbolOfNode(container.parent);
+                return getTypeOfSymbol(symbol);
+            }
+            else {
+                var symbol = getSymbolOfNode(container);
+                return getTypeOfSymbol(symbol);
+            }
+        }
+        function getTypeOfParameter(symbol) {
+            var type = getTypeOfSymbol(symbol);
+            if (strictNullChecks) {
+                var declaration = symbol.valueDeclaration;
+                if (declaration && declaration.initializer) {
+                    return getNullableType(type, 2048 /* Undefined */);
+                }
+            }
+            return type;
+        }
+        function getTypeAtPosition(signature, pos) {
+            return signature.hasRestParameter ?
+                pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
+                pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos]) : anyType;
+        }
+        function getTypeOfFirstParameterOfSignature(signature) {
+            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
+        }
+        function inferFromAnnotatedParameters(signature, context, mapper) {
+            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
+            for (var i = 0; i < len; i++) {
+                var declaration = signature.parameters[i].valueDeclaration;
+                if (declaration.type) {
+                    var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
+                    if (typeNode) {
+                        inferTypes(mapper.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
+                    }
+                }
+            }
+        }
+        function assignContextualParameterTypes(signature, context) {
+            signature.typeParameters = context.typeParameters;
+            if (context.thisParameter) {
+                var parameter = signature.thisParameter;
+                if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) {
+                    if (!parameter) {
+                        signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
+                    }
+                    assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
+                }
+            }
+            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
+            for (var i = 0; i < len; i++) {
+                var parameter = signature.parameters[i];
+                if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
+                    var contextualParameterType = getTypeAtPosition(context, i);
+                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
+                }
+            }
+            if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
+                // parameter might be a transient symbol generated by use of `arguments` in the function body.
+                var parameter = ts.lastOrUndefined(signature.parameters);
+                if (isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
+                    var contextualParameterType = getTypeOfSymbol(ts.lastOrUndefined(context.parameters));
+                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
+                }
+            }
+        }
+        // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
+        // the destructured type into the contained binding elements.
+        function assignBindingElementTypes(pattern) {
+            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
+                var element = _a[_i];
+                if (!ts.isOmittedExpression(element)) {
+                    if (element.name.kind === 71 /* Identifier */) {
+                        getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
+                    }
+                    else {
+                        assignBindingElementTypes(element.name);
+                    }
+                }
+            }
+        }
+        function assignTypeToParameterAndFixTypeParameters(parameter, contextualType) {
+            var links = getSymbolLinks(parameter);
+            if (!links.type) {
+                links.type = contextualType;
+                var decl = parameter.valueDeclaration;
+                if (decl.name.kind !== 71 /* Identifier */) {
+                    // if inference didn't come up with anything but {}, fall back to the binding pattern if present.
+                    if (links.type === emptyObjectType) {
+                        links.type = getTypeFromBindingPattern(decl.name);
+                    }
+                    assignBindingElementTypes(decl.name);
+                }
+            }
+        }
+        function createPromiseType(promisedType) {
+            // creates a `Promise<T>` type where `T` is the promisedType argument
+            var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
+            if (globalPromiseType !== emptyGenericType) {
+                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
+                promisedType = getAwaitedType(promisedType) || emptyObjectType;
+                return createTypeReference(globalPromiseType, [promisedType]);
+            }
+            return emptyObjectType;
+        }
+        function createPromiseReturnType(func, promisedType) {
+            var promiseType = createPromiseType(promisedType);
+            if (promiseType === emptyObjectType) {
+                error(func, ts.isImportCall(func) ?
+                    ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
+                    ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
+                return unknownType;
+            }
+            else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
+                error(func, ts.isImportCall(func) ?
+                    ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
+                    ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
+            }
+            return promiseType;
+        }
+        function getReturnTypeFromBody(func, checkMode) {
+            var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
+            if (!func.body) {
+                return unknownType;
+            }
+            var functionFlags = ts.getFunctionFlags(func);
+            var type;
+            if (func.body.kind !== 207 /* Block */) {
+                type = checkExpressionCached(func.body, checkMode);
+                if (functionFlags & 2 /* Async */) {
+                    // From within an async function you can return either a non-promise value or a promise. Any
+                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
+                    // return type of the body should be unwrapped to its awaited type, which we will wrap in
+                    // the native Promise<T> type later in this function.
+                    type = checkAwaitedType(type, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+                }
+            }
+            else {
+                var types = void 0;
+                if (functionFlags & 1 /* Generator */) {
+                    types = ts.concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), checkAndAggregateReturnExpressionTypes(func, checkMode));
+                    if (!types || types.length === 0) {
+                        var iterableIteratorAny = functionFlags & 2 /* Async */
+                            ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function
+                            : createIterableIteratorType(anyType); // Generator function
+                        if (noImplicitAny) {
+                            error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny));
+                        }
+                        return iterableIteratorAny;
+                    }
+                }
+                else {
+                    types = checkAndAggregateReturnExpressionTypes(func, checkMode);
+                    if (!types) {
+                        // For an async function, the return type will not be never, but rather a Promise for never.
+                        return functionFlags & 2 /* Async */
+                            ? createPromiseReturnType(func, neverType) // Async function
+                            : neverType; // Normal function
+                    }
+                    if (types.length === 0) {
+                        // For an async function, the return type will not be void, but rather a Promise for void.
+                        return functionFlags & 2 /* Async */
+                            ? createPromiseReturnType(func, voidType) // Async function
+                            : voidType; // Normal function
+                    }
+                }
+                // Return a union of the return expression types.
+                type = getUnionType(types, /*subtypeReduction*/ true);
+                if (functionFlags & 1 /* Generator */) {
+                    type = functionFlags & 2 /* Async */
+                        ? createAsyncIterableIteratorType(type) // AsyncGenerator function
+                        : createIterableIteratorType(type); // Generator function
+                }
+            }
+            if (!contextualSignature) {
+                reportErrorsFromWidening(func, type);
+            }
+            if (isUnitType(type) &&
+                !(contextualSignature &&
+                    isLiteralContextualType(contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature)))) {
+                type = getWidenedLiteralType(type);
+            }
+            var widenedType = getWidenedType(type);
+            // From within an async function you can return either a non-promise value or a promise. Any
+            // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
+            // return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
+            return (functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */
+                ? createPromiseReturnType(func, widenedType) // Async function
+                : widenedType; // Generator function, AsyncGenerator function, or normal function
+        }
+        function checkAndAggregateYieldOperandTypes(func, checkMode) {
+            var aggregatedTypes = [];
+            var functionFlags = ts.getFunctionFlags(func);
+            ts.forEachYieldExpression(func.body, function (yieldExpression) {
+                var expr = yieldExpression.expression;
+                if (expr) {
+                    var type = checkExpressionCached(expr, checkMode);
+                    if (yieldExpression.asteriskToken) {
+                        // A yield* expression effectively yields everything that its operand yields
+                        type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0);
+                    }
+                    if (functionFlags & 2 /* Async */) {
+                        type = checkAwaitedType(type, expr, yieldExpression.asteriskToken
+                            ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
+                            : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+                    }
+                    ts.pushIfUnique(aggregatedTypes, type);
+                }
+            });
+            return aggregatedTypes;
+        }
+        function isExhaustiveSwitchStatement(node) {
+            if (!node.possiblyExhaustive) {
+                return false;
+            }
+            var type = getTypeOfExpression(node.expression);
+            if (!isLiteralType(type)) {
+                return false;
+            }
+            var switchTypes = getSwitchClauseTypes(node);
+            if (!switchTypes.length) {
+                return false;
+            }
+            return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
+        }
+        function functionHasImplicitReturn(func) {
+            if (!(func.flags & 128 /* HasImplicitReturn */)) {
+                return false;
+            }
+            var lastStatement = ts.lastOrUndefined(func.body.statements);
+            if (lastStatement && lastStatement.kind === 221 /* SwitchStatement */ && isExhaustiveSwitchStatement(lastStatement)) {
+                return false;
+            }
+            return true;
+        }
+        function checkAndAggregateReturnExpressionTypes(func, checkMode) {
+            var functionFlags = ts.getFunctionFlags(func);
+            var aggregatedTypes = [];
+            var hasReturnWithNoExpression = functionHasImplicitReturn(func);
+            var hasReturnOfTypeNever = false;
+            ts.forEachReturnStatement(func.body, function (returnStatement) {
+                var expr = returnStatement.expression;
+                if (expr) {
+                    var type = checkExpressionCached(expr, checkMode);
+                    if (functionFlags & 2 /* Async */) {
+                        // From within an async function you can return either a non-promise value or a promise. Any
+                        // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
+                        // return type of the body should be unwrapped to its awaited type, which should be wrapped in
+                        // the native Promise<T> type by the caller.
+                        type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+                    }
+                    if (type.flags & 8192 /* Never */) {
+                        hasReturnOfTypeNever = true;
+                    }
+                    ts.pushIfUnique(aggregatedTypes, type);
+                }
+                else {
+                    hasReturnWithNoExpression = true;
+                }
+            });
+            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever ||
+                func.kind === 186 /* FunctionExpression */ || func.kind === 187 /* ArrowFunction */)) {
+                return undefined;
+            }
+            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) {
+                ts.pushIfUnique(aggregatedTypes, undefinedType);
+            }
+            return aggregatedTypes;
+        }
+        /**
+         * TypeScript Specification 1.0 (6.3) - July 2014
+         *   An explicitly typed function whose return type isn't the Void type,
+         *   the Any type, or a union type containing the Void or Any type as a constituent
+         *   must have at least one return statement somewhere in its body.
+         *   An exception to this rule is if the function implementation consists of a single 'throw' statement.
+         *
+         * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
+         */
+        function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) {
+            if (!produceDiagnostics) {
+                return;
+            }
+            // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
+            if (returnType && maybeTypeOfKind(returnType, 1 /* Any */ | 1024 /* Void */)) {
+                return;
+            }
+            // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
+            // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
+            if (ts.nodeIsMissing(func.body) || func.body.kind !== 207 /* Block */ || !functionHasImplicitReturn(func)) {
+                return;
+            }
+            var hasExplicitReturn = func.flags & 256 /* HasExplicitReturn */;
+            if (returnType && returnType.flags & 8192 /* Never */) {
+                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
+            }
+            else if (returnType && !hasExplicitReturn) {
+                // minimal check: function has syntactic return type annotation and no explicit return statements in the body
+                // this function does not conform to the specification.
+                // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
+                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
+            }
+            else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
+                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
+            }
+            else if (compilerOptions.noImplicitReturns) {
+                if (!returnType) {
+                    // If return type annotation is omitted check if function has any explicit return statements.
+                    // If it does not have any - its inferred return type is void - don't do any checks.
+                    // Otherwise get inferred return type from function body and report error only if it is not void / anytype
+                    if (!hasExplicitReturn) {
+                        return;
+                    }
+                    var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
+                    if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) {
+                        return;
+                    }
+                }
+                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
+            }
+        }
+        function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
+            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
+            // The identityMapper object is used to indicate that function expressions are wildcards
+            if (checkMode === 1 /* SkipContextSensitive */ && isContextSensitive(node)) {
+                checkNodeDeferred(node);
+                return anyFunctionType;
+            }
+            // Grammar checking
+            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
+            if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) {
+                checkGrammarForGenerator(node);
+            }
+            var links = getNodeLinks(node);
+            var type = getTypeOfSymbol(node.symbol);
+            // Check if function expression is contextually typed and assign parameter types if so.
+            if (!(links.flags & 1024 /* ContextChecked */)) {
+                var contextualSignature = getContextualSignature(node);
+                // If a type check is started at a function expression that is an argument of a function call, obtaining the
+                // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
+                // already assigned contextual types.
+                if (!(links.flags & 1024 /* ContextChecked */)) {
+                    links.flags |= 1024 /* ContextChecked */;
+                    if (contextualSignature) {
+                        var signature = getSignaturesOfType(type, 0 /* Call */)[0];
+                        if (isContextSensitive(node)) {
+                            var contextualMapper = getContextualMapper(node);
+                            if (checkMode === 2 /* Inferential */) {
+                                inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
+                            }
+                            var instantiatedContextualSignature = contextualMapper === identityMapper ?
+                                contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
+                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
+                        }
+                        if (!ts.getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
+                            var returnType = getReturnTypeFromBody(node, checkMode);
+                            if (!signature.resolvedReturnType) {
+                                signature.resolvedReturnType = returnType;
+                            }
+                        }
+                    }
+                    checkSignatureDeclaration(node);
+                    checkNodeDeferred(node);
+                }
+            }
+            if (produceDiagnostics && node.kind !== 151 /* MethodDeclaration */) {
+                checkCollisionWithCapturedSuperVariable(node, node.name);
+                checkCollisionWithCapturedThisVariable(node, node.name);
+                checkCollisionWithCapturedNewTargetVariable(node, node.name);
+            }
+            return type;
+        }
+        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
+            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
+            var functionFlags = ts.getFunctionFlags(node);
+            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
+            var returnOrPromisedType = returnTypeNode &&
+                ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ ?
+                    checkAsyncFunctionReturnType(node) : // Async function
+                    getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function
+            if ((functionFlags & 1 /* Generator */) === 0) {
+                // return is not necessary in the body of generators
+                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
+            }
+            if (node.body) {
+                if (!returnTypeNode) {
+                    // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
+                    // we need. An example is the noImplicitAny errors resulting from widening the return expression
+                    // of a function. Because checking of function expression bodies is deferred, there was never an
+                    // appropriate time to do this during the main walk of the file (see the comment at the top of
+                    // checkFunctionExpressionBodies). So it must be done now.
+                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
+                }
+                if (node.body.kind === 207 /* Block */) {
+                    checkSourceElement(node.body);
+                }
+                else {
+                    // From within an async function you can return either a non-promise value or a promise. Any
+                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so we
+                    // should not be checking assignability of a promise to the return type. Instead, we need to
+                    // check assignability of the awaited type of the expression body against the promised type of
+                    // its return type annotation.
+                    var exprType = checkExpression(node.body);
+                    if (returnOrPromisedType) {
+                        if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) {
+                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+                            checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body);
+                        }
+                        else {
+                            checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
+                        }
+                    }
+                }
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkArithmeticOperandType(operand, type, diagnostic) {
+            if (!isTypeAssignableToKind(type, 84 /* NumberLike */)) {
+                error(operand, diagnostic);
+                return false;
+            }
+            return true;
+        }
+        function isReadonlySymbol(symbol) {
+            // The following symbols are considered read-only:
+            // Properties with a 'readonly' modifier
+            // Variables declared with 'const'
+            // Get accessors without matching set accessors
+            // Enum members
+            // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
+            return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ ||
+                symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ ||
+                symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ ||
+                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
+                symbol.flags & 8 /* EnumMember */);
+        }
+        function isReferenceToReadonlyEntity(expr, symbol) {
+            if (isReadonlySymbol(symbol)) {
+                // Allow assignments to readonly properties within constructors of the same class declaration.
+                if (symbol.flags & 4 /* Property */ &&
+                    (expr.kind === 179 /* PropertyAccessExpression */ || expr.kind === 180 /* ElementAccessExpression */) &&
+                    expr.expression.kind === 99 /* ThisKeyword */) {
+                    // Look for if this is the constructor for the class that `symbol` is a property of.
+                    var func = ts.getContainingFunction(expr);
+                    if (!(func && func.kind === 152 /* Constructor */)) {
+                        return true;
+                    }
+                    // If func.parent is a class and symbol is a (readonly) property of that class, or
+                    // if func is a constructor and symbol is a (readonly) parameter property declared in it,
+                    // then symbol is writeable here.
+                    return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent);
+                }
+                return true;
+            }
+            return false;
+        }
+        function isReferenceThroughNamespaceImport(expr) {
+            if (expr.kind === 179 /* PropertyAccessExpression */ || expr.kind === 180 /* ElementAccessExpression */) {
+                var node = ts.skipParentheses(expr.expression);
+                if (node.kind === 71 /* Identifier */) {
+                    var symbol = getNodeLinks(node).resolvedSymbol;
+                    if (symbol.flags & 2097152 /* Alias */) {
+                        var declaration = getDeclarationOfAliasSymbol(symbol);
+                        return declaration && declaration.kind === 240 /* NamespaceImport */;
+                    }
+                }
+            }
+            return false;
+        }
+        function checkReferenceExpression(expr, invalidReferenceMessage) {
+            // References are combinations of identifiers, parentheses, and property accesses.
+            var node = ts.skipOuterExpressions(expr, 2 /* Assertions */ | 1 /* Parentheses */);
+            if (node.kind !== 71 /* Identifier */ && node.kind !== 179 /* PropertyAccessExpression */ && node.kind !== 180 /* ElementAccessExpression */) {
+                error(expr, invalidReferenceMessage);
+                return false;
+            }
+            return true;
+        }
+        function checkDeleteExpression(node) {
+            checkExpression(node.expression);
+            var expr = ts.skipParentheses(node.expression);
+            if (expr.kind !== 179 /* PropertyAccessExpression */ && expr.kind !== 180 /* ElementAccessExpression */) {
+                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference);
+                return booleanType;
+            }
+            var links = getNodeLinks(expr);
+            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
+            if (symbol && isReadonlySymbol(symbol)) {
+                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property);
+            }
+            return booleanType;
+        }
+        function checkTypeOfExpression(node) {
+            checkExpression(node.expression);
+            return typeofType;
+        }
+        function checkVoidExpression(node) {
+            checkExpression(node.expression);
+            return undefinedWideningType;
+        }
+        function checkAwaitExpression(node) {
+            // Grammar checking
+            if (produceDiagnostics) {
+                if (!(node.flags & 16384 /* AwaitContext */)) {
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function);
+                }
+                if (isInParameterInitializerBeforeContainingFunction(node)) {
+                    error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
+                }
+            }
+            var operandType = checkExpression(node.expression);
+            return checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+        }
+        function checkPrefixUnaryExpression(node) {
+            var operandType = checkExpression(node.operand);
+            if (operandType === silentNeverType) {
+                return silentNeverType;
+            }
+            if (node.operand.kind === 8 /* NumericLiteral */) {
+                if (node.operator === 38 /* MinusToken */) {
+                    return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text));
+                }
+                else if (node.operator === 37 /* PlusToken */) {
+                    return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text));
+                }
+            }
+            switch (node.operator) {
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 52 /* TildeToken */:
+                    checkNonNullType(operandType, node.operand);
+                    if (maybeTypeOfKind(operandType, 512 /* ESSymbol */)) {
+                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
+                    }
+                    return numberType;
+                case 51 /* ExclamationToken */:
+                    var facts = getTypeFacts(operandType) & (1048576 /* Truthy */ | 2097152 /* Falsy */);
+                    return facts === 1048576 /* Truthy */ ? falseType :
+                        facts === 2097152 /* Falsy */ ? trueType :
+                            booleanType;
+                case 43 /* PlusPlusToken */:
+                case 44 /* MinusMinusToken */:
+                    var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
+                    if (ok) {
+                        // run check only if former checks succeeded to avoid reporting cascading errors
+                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
+                    }
+                    return numberType;
+            }
+            return unknownType;
+        }
+        function checkPostfixUnaryExpression(node) {
+            var operandType = checkExpression(node.operand);
+            if (operandType === silentNeverType) {
+                return silentNeverType;
+            }
+            var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
+            if (ok) {
+                // run check only if former checks succeeded to avoid reporting cascading errors
+                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
+            }
+            return numberType;
+        }
+        // Return true if type might be of the given kind. A union or intersection type might be of a given
+        // kind if at least one constituent type is of the given kind.
+        function maybeTypeOfKind(type, kind) {
+            if (type.flags & kind) {
+                return true;
+            }
+            if (type.flags & 196608 /* UnionOrIntersection */) {
+                var types = type.types;
+                for (var _i = 0, types_18 = types; _i < types_18.length; _i++) {
+                    var t = types_18[_i];
+                    if (maybeTypeOfKind(t, kind)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        function isTypeAssignableToKind(source, kind, strict) {
+            if (source.flags & kind) {
+                return true;
+            }
+            if (strict && source.flags & (1 /* Any */ | 1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */)) {
+                return false;
+            }
+            return (kind & 84 /* NumberLike */ && isTypeAssignableTo(source, numberType)) ||
+                (kind & 262178 /* StringLike */ && isTypeAssignableTo(source, stringType)) ||
+                (kind & 136 /* BooleanLike */ && isTypeAssignableTo(source, booleanType)) ||
+                (kind & 1024 /* Void */ && isTypeAssignableTo(source, voidType)) ||
+                (kind & 8192 /* Never */ && isTypeAssignableTo(source, neverType)) ||
+                (kind & 4096 /* Null */ && isTypeAssignableTo(source, nullType)) ||
+                (kind & 2048 /* Undefined */ && isTypeAssignableTo(source, undefinedType)) ||
+                (kind & 512 /* ESSymbol */ && isTypeAssignableTo(source, esSymbolType)) ||
+                (kind & 16777216 /* NonPrimitive */ && isTypeAssignableTo(source, nonPrimitiveType));
+        }
+        function isConstEnumObjectType(type) {
+            return getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && isConstEnumSymbol(type.symbol);
+        }
+        function isConstEnumSymbol(symbol) {
+            return (symbol.flags & 128 /* ConstEnum */) !== 0;
+        }
+        function checkInstanceOfExpression(left, right, leftType, rightType) {
+            if (leftType === silentNeverType || rightType === silentNeverType) {
+                return silentNeverType;
+            }
+            // TypeScript 1.0 spec (April 2014): 4.15.4
+            // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
+            // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
+            // The result is always of the Boolean primitive type.
+            // NOTE: do not raise error if leftType is unknown as related error was already reported
+            if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190 /* Primitive */)) {
+                error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
+            }
+            // NOTE: do not raise error if right is unknown as related error was already reported
+            if (!(isTypeAny(rightType) ||
+                getSignaturesOfType(rightType, 0 /* Call */).length ||
+                getSignaturesOfType(rightType, 1 /* Construct */).length ||
+                isTypeSubtypeOf(rightType, globalFunctionType))) {
+                error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
+            }
+            return booleanType;
+        }
+        function checkInExpression(left, right, leftType, rightType) {
+            if (leftType === silentNeverType || rightType === silentNeverType) {
+                return silentNeverType;
+            }
+            leftType = checkNonNullType(leftType, left);
+            rightType = checkNonNullType(rightType, right);
+            // TypeScript 1.0 spec (April 2014): 4.15.5
+            // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
+            // and the right operand to be of type Any, an object type, or a type parameter type.
+            // The result is always of the Boolean primitive type.
+            if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) {
+                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
+            }
+            if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) {
+                error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
+            }
+            return booleanType;
+        }
+        function checkObjectLiteralAssignment(node, sourceType) {
+            var properties = node.properties;
+            for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) {
+                var p = properties_7[_i];
+                checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
+            }
+            return sourceType;
+        }
+        /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
+        function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType, property, allProperties) {
+            if (property.kind === 261 /* PropertyAssignment */ || property.kind === 262 /* ShorthandPropertyAssignment */) {
+                var name = property.name;
+                if (name.kind === 144 /* ComputedPropertyName */) {
+                    checkComputedPropertyName(name);
+                }
+                if (isComputedNonLiteralName(name)) {
+                    return undefined;
+                }
+                var text = ts.getTextOfPropertyName(name);
+                var type = isTypeAny(objectLiteralType)
+                    ? objectLiteralType
+                    : getTypeOfPropertyOfType(objectLiteralType, text) ||
+                        isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, 1 /* Number */) ||
+                        getIndexTypeOfType(objectLiteralType, 0 /* String */);
+                if (type) {
+                    if (property.kind === 262 /* ShorthandPropertyAssignment */) {
+                        return checkDestructuringAssignment(property, type);
+                    }
+                    else {
+                        // non-shorthand property assignments should always have initializers
+                        return checkDestructuringAssignment(property.initializer, type);
+                    }
+                }
+                else {
+                    error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), ts.declarationNameToString(name));
+                }
+            }
+            else if (property.kind === 263 /* SpreadAssignment */) {
+                if (languageVersion < 5 /* ESNext */) {
+                    checkExternalEmitHelpers(property, 4 /* Rest */);
+                }
+                var nonRestNames = [];
+                if (allProperties) {
+                    for (var i = 0; i < allProperties.length - 1; i++) {
+                        nonRestNames.push(allProperties[i].name);
+                    }
+                }
+                var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
+                return checkDestructuringAssignment(property.expression, type);
+            }
+            else {
+                error(property, ts.Diagnostics.Property_assignment_expected);
+            }
+        }
+        function checkArrayLiteralAssignment(node, sourceType, checkMode) {
+            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
+                checkExternalEmitHelpers(node, 512 /* Read */);
+            }
+            // This elementType will be used if the specific property corresponding to this index is not
+            // present (aka the tuple element property). This call also checks that the parentType is in
+            // fact an iterable or array (depending on target language).
+            var elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType;
+            var elements = node.elements;
+            for (var i = 0; i < elements.length; i++) {
+                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
+            }
+            return sourceType;
+        }
+        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) {
+            var elements = node.elements;
+            var element = elements[elementIndex];
+            if (element.kind !== 200 /* OmittedExpression */) {
+                if (element.kind !== 198 /* SpreadElement */) {
+                    var propName = "" + elementIndex;
+                    var type = isTypeAny(sourceType)
+                        ? sourceType
+                        : isTupleLikeType(sourceType)
+                            ? getTypeOfPropertyOfType(sourceType, propName)
+                            : elementType;
+                    if (type) {
+                        return checkDestructuringAssignment(element, type, checkMode);
+                    }
+                    else {
+                        // We still need to check element expression here because we may need to set appropriate flag on the expression
+                        // such as NodeCheckFlags.LexicalThis on "this"expression.
+                        checkExpression(element);
+                        if (isTupleType(sourceType)) {
+                            error(element, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length);
+                        }
+                        else {
+                            error(element, ts.Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
+                        }
+                    }
+                }
+                else {
+                    if (elementIndex < elements.length - 1) {
+                        error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
+                    }
+                    else {
+                        var restExpression = element.expression;
+                        if (restExpression.kind === 194 /* BinaryExpression */ && restExpression.operatorToken.kind === 58 /* EqualsToken */) {
+                            error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
+                        }
+                        else {
+                            return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode);
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode) {
+            var target;
+            if (exprOrAssignment.kind === 262 /* ShorthandPropertyAssignment */) {
+                var prop = exprOrAssignment;
+                if (prop.objectAssignmentInitializer) {
+                    // In strict null checking mode, if a default value of a non-undefined type is specified, remove
+                    // undefined from the final type.
+                    if (strictNullChecks &&
+                        !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 2048 /* Undefined */)) {
+                        sourceType = getTypeWithFacts(sourceType, 131072 /* NEUndefined */);
+                    }
+                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
+                }
+                target = exprOrAssignment.name;
+            }
+            else {
+                target = exprOrAssignment;
+            }
+            if (target.kind === 194 /* BinaryExpression */ && target.operatorToken.kind === 58 /* EqualsToken */) {
+                checkBinaryExpression(target, checkMode);
+                target = target.left;
+            }
+            if (target.kind === 178 /* ObjectLiteralExpression */) {
+                return checkObjectLiteralAssignment(target, sourceType);
+            }
+            if (target.kind === 177 /* ArrayLiteralExpression */) {
+                return checkArrayLiteralAssignment(target, sourceType, checkMode);
+            }
+            return checkReferenceAssignment(target, sourceType, checkMode);
+        }
+        function checkReferenceAssignment(target, sourceType, checkMode) {
+            var targetType = checkExpression(target, checkMode);
+            var error = target.parent.kind === 263 /* SpreadAssignment */ ?
+                ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
+                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
+            if (checkReferenceExpression(target, error)) {
+                checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined);
+            }
+            return sourceType;
+        }
+        /**
+         * This is a *shallow* check: An expression is side-effect-free if the
+         * evaluation of the expression *itself* cannot produce side effects.
+         * For example, x++ / 3 is side-effect free because the / operator
+         * does not have side effects.
+         * The intent is to "smell test" an expression for correctness in positions where
+         * its value is discarded (e.g. the left side of the comma operator).
+         */
+        function isSideEffectFree(node) {
+            node = ts.skipParentheses(node);
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                case 9 /* StringLiteral */:
+                case 12 /* RegularExpressionLiteral */:
+                case 183 /* TaggedTemplateExpression */:
+                case 196 /* TemplateExpression */:
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                case 8 /* NumericLiteral */:
+                case 101 /* TrueKeyword */:
+                case 86 /* FalseKeyword */:
+                case 95 /* NullKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 186 /* FunctionExpression */:
+                case 199 /* ClassExpression */:
+                case 187 /* ArrowFunction */:
+                case 177 /* ArrayLiteralExpression */:
+                case 178 /* ObjectLiteralExpression */:
+                case 189 /* TypeOfExpression */:
+                case 203 /* NonNullExpression */:
+                case 250 /* JsxSelfClosingElement */:
+                case 249 /* JsxElement */:
+                    return true;
+                case 195 /* ConditionalExpression */:
+                    return isSideEffectFree(node.whenTrue) &&
+                        isSideEffectFree(node.whenFalse);
+                case 194 /* BinaryExpression */:
+                    if (ts.isAssignmentOperator(node.operatorToken.kind)) {
+                        return false;
+                    }
+                    return isSideEffectFree(node.left) &&
+                        isSideEffectFree(node.right);
+                case 192 /* PrefixUnaryExpression */:
+                case 193 /* PostfixUnaryExpression */:
+                    // Unary operators ~, !, +, and - have no side effects.
+                    // The rest do.
+                    switch (node.operator) {
+                        case 51 /* ExclamationToken */:
+                        case 37 /* PlusToken */:
+                        case 38 /* MinusToken */:
+                        case 52 /* TildeToken */:
+                            return true;
+                    }
+                    return false;
+                // Some forms listed here for clarity
+                case 190 /* VoidExpression */: // Explicit opt-out
+                case 184 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings
+                case 202 /* AsExpression */: // Not SEF, but can produce useful type warnings
+                default:
+                    return false;
+            }
+        }
+        function isTypeEqualityComparableTo(source, target) {
+            return (target.flags & 6144 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
+        }
+        function getBestChoiceType(type1, type2) {
+            var firstAssignableToSecond = isTypeAssignableTo(type1, type2);
+            var secondAssignableToFirst = isTypeAssignableTo(type2, type1);
+            return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
+                firstAssignableToSecond && !secondAssignableToFirst ? type2 :
+                    getUnionType([type1, type2], /*subtypeReduction*/ true);
+        }
+        function checkBinaryExpression(node, checkMode) {
+            return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
+        }
+        function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) {
+            var operator = operatorToken.kind;
+            if (operator === 58 /* EqualsToken */ && (left.kind === 178 /* ObjectLiteralExpression */ || left.kind === 177 /* ArrayLiteralExpression */)) {
+                return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode);
+            }
+            var leftType = checkExpression(left, checkMode);
+            var rightType = checkExpression(right, checkMode);
+            switch (operator) {
+                case 39 /* AsteriskToken */:
+                case 40 /* AsteriskAsteriskToken */:
+                case 61 /* AsteriskEqualsToken */:
+                case 62 /* AsteriskAsteriskEqualsToken */:
+                case 41 /* SlashToken */:
+                case 63 /* SlashEqualsToken */:
+                case 42 /* PercentToken */:
+                case 64 /* PercentEqualsToken */:
+                case 38 /* MinusToken */:
+                case 60 /* MinusEqualsToken */:
+                case 45 /* LessThanLessThanToken */:
+                case 65 /* LessThanLessThanEqualsToken */:
+                case 46 /* GreaterThanGreaterThanToken */:
+                case 66 /* GreaterThanGreaterThanEqualsToken */:
+                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                case 49 /* BarToken */:
+                case 69 /* BarEqualsToken */:
+                case 50 /* CaretToken */:
+                case 70 /* CaretEqualsToken */:
+                case 48 /* AmpersandToken */:
+                case 68 /* AmpersandEqualsToken */:
+                    if (leftType === silentNeverType || rightType === silentNeverType) {
+                        return silentNeverType;
+                    }
+                    leftType = checkNonNullType(leftType, left);
+                    rightType = checkNonNullType(rightType, right);
+                    var suggestedOperator = void 0;
+                    // if a user tries to apply a bitwise operator to 2 boolean operands
+                    // try and return them a helpful suggestion
+                    if ((leftType.flags & 136 /* BooleanLike */) &&
+                        (rightType.flags & 136 /* BooleanLike */) &&
+                        (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
+                        error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator));
+                    }
+                    else {
+                        // otherwise just check each operand separately and report errors as normal
+                        var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
+                        var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
+                        if (leftOk && rightOk) {
+                            checkAssignmentOperator(numberType);
+                        }
+                    }
+                    return numberType;
+                case 37 /* PlusToken */:
+                case 59 /* PlusEqualsToken */:
+                    if (leftType === silentNeverType || rightType === silentNeverType) {
+                        return silentNeverType;
+                    }
+                    if (!isTypeAssignableToKind(leftType, 262178 /* StringLike */) && !isTypeAssignableToKind(rightType, 262178 /* StringLike */)) {
+                        leftType = checkNonNullType(leftType, left);
+                        rightType = checkNonNullType(rightType, right);
+                    }
+                    var resultType = void 0;
+                    if (isTypeAssignableToKind(leftType, 84 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 84 /* NumberLike */, /*strict*/ true)) {
+                        // Operands of an enum type are treated as having the primitive type Number.
+                        // If both operands are of the Number primitive type, the result is of the Number primitive type.
+                        resultType = numberType;
+                    }
+                    else if (isTypeAssignableToKind(leftType, 262178 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 262178 /* StringLike */, /*strict*/ true)) {
+                        // If one or both operands are of the String primitive type, the result is of the String primitive type.
+                        resultType = stringType;
+                    }
+                    else if (isTypeAny(leftType) || isTypeAny(rightType)) {
+                        // Otherwise, the result is of type Any.
+                        // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
+                        resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType;
+                    }
+                    // Symbols are not allowed at all in arithmetic expressions
+                    if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
+                        return resultType;
+                    }
+                    if (!resultType) {
+                        reportOperatorError();
+                        return anyType;
+                    }
+                    if (operator === 59 /* PlusEqualsToken */) {
+                        checkAssignmentOperator(resultType);
+                    }
+                    return resultType;
+                case 27 /* LessThanToken */:
+                case 29 /* GreaterThanToken */:
+                case 30 /* LessThanEqualsToken */:
+                case 31 /* GreaterThanEqualsToken */:
+                    if (checkForDisallowedESSymbolOperand(operator)) {
+                        leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
+                        rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
+                        if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
+                            reportOperatorError();
+                        }
+                    }
+                    return booleanType;
+                case 32 /* EqualsEqualsToken */:
+                case 33 /* ExclamationEqualsToken */:
+                case 34 /* EqualsEqualsEqualsToken */:
+                case 35 /* ExclamationEqualsEqualsToken */:
+                    var leftIsLiteral = isLiteralType(leftType);
+                    var rightIsLiteral = isLiteralType(rightType);
+                    if (!leftIsLiteral || !rightIsLiteral) {
+                        leftType = leftIsLiteral ? getBaseTypeOfLiteralType(leftType) : leftType;
+                        rightType = rightIsLiteral ? getBaseTypeOfLiteralType(rightType) : rightType;
+                    }
+                    if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
+                        reportOperatorError();
+                    }
+                    return booleanType;
+                case 93 /* InstanceOfKeyword */:
+                    return checkInstanceOfExpression(left, right, leftType, rightType);
+                case 92 /* InKeyword */:
+                    return checkInExpression(left, right, leftType, rightType);
+                case 53 /* AmpersandAmpersandToken */:
+                    return getTypeFacts(leftType) & 1048576 /* Truthy */ ?
+                        getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
+                        leftType;
+                case 54 /* BarBarToken */:
+                    return getTypeFacts(leftType) & 2097152 /* Falsy */ ?
+                        getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) :
+                        leftType;
+                case 58 /* EqualsToken */:
+                    checkAssignmentOperator(rightType);
+                    return getRegularTypeOfObjectLiteral(rightType);
+                case 26 /* CommaToken */:
+                    if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
+                        error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
+                    }
+                    return rightType;
+            }
+            function isEvalNode(node) {
+                return node.kind === 71 /* Identifier */ && node.escapedText === "eval";
+            }
+            // Return true if there was no error, false if there was an error.
+            function checkForDisallowedESSymbolOperand(operator) {
+                var offendingSymbolOperand = maybeTypeOfKind(leftType, 512 /* ESSymbol */) ? left :
+                    maybeTypeOfKind(rightType, 512 /* ESSymbol */) ? right :
+                        undefined;
+                if (offendingSymbolOperand) {
+                    error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator));
+                    return false;
+                }
+                return true;
+            }
+            function getSuggestedBooleanOperator(operator) {
+                switch (operator) {
+                    case 49 /* BarToken */:
+                    case 69 /* BarEqualsToken */:
+                        return 54 /* BarBarToken */;
+                    case 50 /* CaretToken */:
+                    case 70 /* CaretEqualsToken */:
+                        return 35 /* ExclamationEqualsEqualsToken */;
+                    case 48 /* AmpersandToken */:
+                    case 68 /* AmpersandEqualsToken */:
+                        return 53 /* AmpersandAmpersandToken */;
+                    default:
+                        return undefined;
+                }
+            }
+            function checkAssignmentOperator(valueType) {
+                if (produceDiagnostics && ts.isAssignmentOperator(operator)) {
+                    // TypeScript 1.0 spec (April 2014): 4.17
+                    // An assignment of the form
+                    //    VarExpr = ValueExpr
+                    // requires VarExpr to be classified as a reference
+                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
+                    // and the type of the non - compound operation to be assignable to the type of VarExpr.
+                    if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)) {
+                        // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
+                        checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined);
+                    }
+                }
+            }
+            function reportOperatorError() {
+                error(errorNode || operatorToken, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType));
+            }
+        }
+        function isYieldExpressionInClass(node) {
+            var current = node;
+            var parent = node.parent;
+            while (parent) {
+                if (ts.isFunctionLike(parent) && current === parent.body) {
+                    return false;
+                }
+                else if (ts.isClassLike(current)) {
+                    return true;
+                }
+                current = parent;
+                parent = parent.parent;
+            }
+            return false;
+        }
+        function checkYieldExpression(node) {
+            // Grammar checking
+            if (produceDiagnostics) {
+                if (!(node.flags & 4096 /* YieldContext */) || isYieldExpressionInClass(node)) {
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
+                }
+                if (isInParameterInitializerBeforeContainingFunction(node)) {
+                    error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
+                }
+            }
+            if (node.expression) {
+                var func = ts.getContainingFunction(node);
+                // If the user's code is syntactically correct, the func should always have a star. After all,
+                // we are in a yield context.
+                var functionFlags = func && ts.getFunctionFlags(func);
+                if (node.asteriskToken) {
+                    // Async generator functions prior to ESNext require the __await, __asyncDelegator,
+                    // and __asyncValues helpers
+                    if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ &&
+                        languageVersion < 5 /* ESNext */) {
+                        checkExternalEmitHelpers(node, 26624 /* AsyncDelegatorIncludes */);
+                    }
+                    // Generator functions prior to ES2015 require the __values helper
+                    if ((functionFlags & 3 /* AsyncGenerator */) === 1 /* Generator */ &&
+                        languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
+                        checkExternalEmitHelpers(node, 256 /* Values */);
+                    }
+                }
+                if (functionFlags & 1 /* Generator */) {
+                    var expressionType = checkExpressionCached(node.expression);
+                    var expressionElementType = void 0;
+                    var nodeIsYieldStar = !!node.asteriskToken;
+                    if (nodeIsYieldStar) {
+                        expressionElementType = checkIteratedTypeOrElementType(expressionType, node.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0);
+                    }
+                    // There is no point in doing an assignability check if the function
+                    // has no explicit return type because the return type is directly computed
+                    // from the yield expressions.
+                    var returnType = ts.getEffectiveReturnTypeNode(func);
+                    if (returnType) {
+                        var signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & 2 /* Async */) !== 0) || anyType;
+                        if (nodeIsYieldStar) {
+                            checkTypeAssignableTo(functionFlags & 2 /* Async */
+                                ? getAwaitedType(expressionElementType, node.expression, ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
+                                : expressionElementType, signatureElementType, node.expression, 
+                            /*headMessage*/ undefined);
+                        }
+                        else {
+                            checkTypeAssignableTo(functionFlags & 2 /* Async */
+                                ? getAwaitedType(expressionType, node.expression, ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
+                                : expressionType, signatureElementType, node.expression, 
+                            /*headMessage*/ undefined);
+                        }
+                    }
+                }
+            }
+            // Both yield and yield* expressions have type 'any'
+            return anyType;
+        }
+        function checkConditionalExpression(node, checkMode) {
+            checkExpression(node.condition);
+            var type1 = checkExpression(node.whenTrue, checkMode);
+            var type2 = checkExpression(node.whenFalse, checkMode);
+            return getBestChoiceType(type1, type2);
+        }
+        function checkTemplateExpression(node) {
+            // We just want to check each expressions, but we are unconcerned with
+            // the type of each expression, as any value may be coerced into a string.
+            // It is worth asking whether this is what we really want though.
+            // A place where we actually *are* concerned with the expressions' types are
+            // in tagged templates.
+            ts.forEach(node.templateSpans, function (templateSpan) {
+                checkExpression(templateSpan.expression);
+            });
+            return stringType;
+        }
+        function checkExpressionWithContextualType(node, contextualType, contextualMapper) {
+            var saveContextualType = node.contextualType;
+            var saveContextualMapper = node.contextualMapper;
+            node.contextualType = contextualType;
+            node.contextualMapper = contextualMapper;
+            var checkMode = contextualMapper === identityMapper ? 1 /* SkipContextSensitive */ :
+                contextualMapper ? 2 /* Inferential */ : 0 /* Normal */;
+            var result = checkExpression(node, checkMode);
+            node.contextualType = saveContextualType;
+            node.contextualMapper = saveContextualMapper;
+            return result;
+        }
+        function checkExpressionCached(node, checkMode) {
+            var links = getNodeLinks(node);
+            if (!links.resolvedType) {
+                // When computing a type that we're going to cache, we need to ignore any ongoing control flow
+                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
+                // to the top of the stack ensures all transient types are computed from a known point.
+                var saveFlowLoopStart = flowLoopStart;
+                flowLoopStart = flowLoopCount;
+                links.resolvedType = checkExpression(node, checkMode);
+                flowLoopStart = saveFlowLoopStart;
+            }
+            return links.resolvedType;
+        }
+        function isTypeAssertion(node) {
+            node = ts.skipParentheses(node);
+            return node.kind === 184 /* TypeAssertionExpression */ || node.kind === 202 /* AsExpression */;
+        }
+        function checkDeclarationInitializer(declaration) {
+            var type = getTypeOfExpression(declaration.initializer, /*cache*/ true);
+            return ts.getCombinedNodeFlags(declaration) & 2 /* Const */ ||
+                ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration) ||
+                isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type);
+        }
+        function isLiteralContextualType(contextualType) {
+            if (contextualType) {
+                if (contextualType.flags & 540672 /* TypeVariable */) {
+                    var constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
+                    // If the type parameter is constrained to the base primitive type we're checking for,
+                    // consider this a literal context. For example, given a type parameter 'T extends string',
+                    // this causes us to infer string literal types for T.
+                    if (constraint.flags & (2 /* String */ | 4 /* Number */ | 8 /* Boolean */ | 16 /* Enum */)) {
+                        return true;
+                    }
+                    contextualType = constraint;
+                }
+                return maybeTypeOfKind(contextualType, (224 /* Literal */ | 262144 /* Index */));
+            }
+            return false;
+        }
+        function checkExpressionForMutableLocation(node, checkMode, contextualType) {
+            if (arguments.length === 2) {
+                contextualType = getContextualType(node);
+            }
+            var type = checkExpression(node, checkMode);
+            var shouldWiden = isTypeAssertion(node) || isLiteralContextualType(contextualType);
+            return shouldWiden ? type : getWidenedLiteralType(type);
+        }
+        function checkPropertyAssignment(node, checkMode) {
+            // Do not use hasDynamicName here, because that returns false for well known symbols.
+            // We want to perform checkComputedPropertyName for all computed properties, including
+            // well known symbols.
+            if (node.name.kind === 144 /* ComputedPropertyName */) {
+                checkComputedPropertyName(node.name);
+            }
+            return checkExpressionForMutableLocation(node.initializer, checkMode);
+        }
+        function checkObjectLiteralMethod(node, checkMode) {
+            // Grammar checking
+            checkGrammarMethod(node);
+            // Do not use hasDynamicName here, because that returns false for well known symbols.
+            // We want to perform checkComputedPropertyName for all computed properties, including
+            // well known symbols.
+            if (node.name.kind === 144 /* ComputedPropertyName */) {
+                checkComputedPropertyName(node.name);
+            }
+            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
+            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
+        }
+        function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) {
+            if (checkMode === 2 /* Inferential */) {
+                var signature = getSingleCallSignature(type);
+                if (signature && signature.typeParameters) {
+                    var contextualType = getApparentTypeOfContextualType(node);
+                    if (contextualType) {
+                        var contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
+                        if (contextualSignature && !contextualSignature.typeParameters) {
+                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
+                        }
+                    }
+                }
+            }
+            return type;
+        }
+        /**
+         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
+         * with computing the type and may not fully check all contained sub-expressions for errors.
+         * A cache argument of true indicates that if the function performs a full type check, it is ok
+         * to cache the result.
+         */
+        function getTypeOfExpression(node, cache) {
+            // Optimize for the common case of a call to a function with a single non-generic call
+            // signature where we can just fetch the return type without checking the arguments.
+            if (node.kind === 181 /* CallExpression */ && node.expression.kind !== 97 /* SuperKeyword */ && !ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
+                var funcType = checkNonNullExpression(node.expression);
+                var signature = getSingleCallSignature(funcType);
+                if (signature && !signature.typeParameters) {
+                    return getReturnTypeOfSignature(signature);
+                }
+            }
+            // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
+            // should have a parameter that indicates whether full error checking is required such that
+            // we can perform the optimizations locally.
+            return cache ? checkExpressionCached(node) : checkExpression(node);
+        }
+        /**
+         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
+         * with computing the type and may not fully check all contained sub-expressions for errors.
+         * It is intended for uses where you know there is no contextual type,
+         * and requesting the contextual type might cause a circularity or other bad behaviour.
+         * It sets the contextual type of the node to any before calling getTypeOfExpression.
+         */
+        function getContextFreeTypeOfExpression(node) {
+            var saveContextualType = node.contextualType;
+            node.contextualType = anyType;
+            var type = getTypeOfExpression(node);
+            node.contextualType = saveContextualType;
+            return type;
+        }
+        // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
+        // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
+        // expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
+        // conjunction with the generic contextual type. When contextualMapper is equal to the identityMapper function
+        // object, it serves as an indicator that all contained function and arrow expressions should be considered to
+        // have the wildcard function type; this form of type check is used during overload resolution to exclude
+        // contextually typed function and arrow expressions in the initial phase.
+        function checkExpression(node, checkMode) {
+            var type;
+            if (node.kind === 143 /* QualifiedName */) {
+                type = checkQualifiedName(node);
+            }
+            else {
+                var uninstantiatedType = checkExpressionWorker(node, checkMode);
+                type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
+            }
+            if (isConstEnumObjectType(type)) {
+                // enum object type for const enums are only permitted in:
+                // - 'left' in property access
+                // - 'object' in indexed access
+                // - target in rhs of import statement
+                var ok = (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.expression === node) ||
+                    (node.parent.kind === 180 /* ElementAccessExpression */ && node.parent.expression === node) ||
+                    ((node.kind === 71 /* Identifier */ || node.kind === 143 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node));
+                if (!ok) {
+                    error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment);
+                }
+            }
+            return type;
+        }
+        function checkParenthesizedExpression(node, checkMode) {
+            var tag = ts.isInJavaScriptFile(node) ? ts.getJSDocTypeTag(node) : undefined;
+            if (tag) {
+                return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
+            }
+            return checkExpression(node.expression, checkMode);
+        }
+        function checkExpressionWorker(node, checkMode) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return checkIdentifier(node);
+                case 99 /* ThisKeyword */:
+                    return checkThisExpression(node);
+                case 97 /* SuperKeyword */:
+                    return checkSuperExpression(node);
+                case 95 /* NullKeyword */:
+                    return nullWideningType;
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                case 9 /* StringLiteral */:
+                    return getFreshTypeOfLiteralType(getLiteralType(node.text));
+                case 8 /* NumericLiteral */:
+                    checkGrammarNumericLiteral(node);
+                    return getFreshTypeOfLiteralType(getLiteralType(+node.text));
+                case 101 /* TrueKeyword */:
+                    return trueType;
+                case 86 /* FalseKeyword */:
+                    return falseType;
+                case 196 /* TemplateExpression */:
+                    return checkTemplateExpression(node);
+                case 12 /* RegularExpressionLiteral */:
+                    return globalRegExpType;
+                case 177 /* ArrayLiteralExpression */:
+                    return checkArrayLiteral(node, checkMode);
+                case 178 /* ObjectLiteralExpression */:
+                    return checkObjectLiteral(node, checkMode);
+                case 179 /* PropertyAccessExpression */:
+                    return checkPropertyAccessExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return checkIndexedAccess(node);
+                case 181 /* CallExpression */:
+                    if (node.expression.kind === 91 /* ImportKeyword */) {
+                        return checkImportCallExpression(node);
+                    }
+                /* falls through */
+                case 182 /* NewExpression */:
+                    return checkCallExpression(node);
+                case 183 /* TaggedTemplateExpression */:
+                    return checkTaggedTemplateExpression(node);
+                case 185 /* ParenthesizedExpression */:
+                    return checkParenthesizedExpression(node, checkMode);
+                case 199 /* ClassExpression */:
+                    return checkClassExpression(node);
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
+                case 189 /* TypeOfExpression */:
+                    return checkTypeOfExpression(node);
+                case 184 /* TypeAssertionExpression */:
+                case 202 /* AsExpression */:
+                    return checkAssertion(node);
+                case 203 /* NonNullExpression */:
+                    return checkNonNullAssertion(node);
+                case 204 /* MetaProperty */:
+                    return checkMetaProperty(node);
+                case 188 /* DeleteExpression */:
+                    return checkDeleteExpression(node);
+                case 190 /* VoidExpression */:
+                    return checkVoidExpression(node);
+                case 191 /* AwaitExpression */:
+                    return checkAwaitExpression(node);
+                case 192 /* PrefixUnaryExpression */:
+                    return checkPrefixUnaryExpression(node);
+                case 193 /* PostfixUnaryExpression */:
+                    return checkPostfixUnaryExpression(node);
+                case 194 /* BinaryExpression */:
+                    return checkBinaryExpression(node, checkMode);
+                case 195 /* ConditionalExpression */:
+                    return checkConditionalExpression(node, checkMode);
+                case 198 /* SpreadElement */:
+                    return checkSpreadExpression(node, checkMode);
+                case 200 /* OmittedExpression */:
+                    return undefinedWideningType;
+                case 197 /* YieldExpression */:
+                    return checkYieldExpression(node);
+                case 256 /* JsxExpression */:
+                    return checkJsxExpression(node, checkMode);
+                case 249 /* JsxElement */:
+                    return checkJsxElement(node);
+                case 250 /* JsxSelfClosingElement */:
+                    return checkJsxSelfClosingElement(node);
+                case 254 /* JsxAttributes */:
+                    return checkJsxAttributes(node, checkMode);
+                case 251 /* JsxOpeningElement */:
+                    ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
+            }
+            return unknownType;
+        }
+        // DECLARATION AND STATEMENT TYPE CHECKING
+        function checkTypeParameter(node) {
+            // Grammar Checking
+            if (node.expression) {
+                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
+            }
+            checkSourceElement(node.constraint);
+            checkSourceElement(node.default);
+            var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
+            if (!hasNonCircularBaseConstraint(typeParameter)) {
+                error(node.constraint, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
+            }
+            if (!hasNonCircularTypeParameterDefault(typeParameter)) {
+                error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
+            }
+            var constraintType = getConstraintOfTypeParameter(typeParameter);
+            var defaultType = getDefaultFromTypeParameter(typeParameter);
+            if (constraintType && defaultType) {
+                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
+            }
+            if (produceDiagnostics) {
+                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
+            }
+        }
+        function checkParameter(node) {
+            // Grammar checking
+            // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
+            // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
+            // or if its FunctionBody is strict code(11.1.5).
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node);
+            checkVariableLikeDeclaration(node);
+            var func = ts.getContainingFunction(node);
+            if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
+                if (!(func.kind === 152 /* Constructor */ && ts.nodeIsPresent(func.body))) {
+                    error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
+                }
+            }
+            if (node.questionToken && ts.isBindingPattern(node.name) && func.body) {
+                error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
+            }
+            if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) {
+                if (ts.indexOf(func.parameters, node) !== 0) {
+                    error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText);
+                }
+                if (func.kind === 152 /* Constructor */ || func.kind === 156 /* ConstructSignature */ || func.kind === 161 /* ConstructorType */) {
+                    error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter);
+                }
+            }
+            // Only check rest parameter type if it's not a binding pattern. Since binding patterns are
+            // not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
+            if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isArrayType(getTypeOfSymbol(node.symbol))) {
+                error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
+            }
+        }
+        function getTypePredicateParameterIndex(parameterList, parameter) {
+            if (parameterList) {
+                for (var i = 0; i < parameterList.length; i++) {
+                    var param = parameterList[i];
+                    if (param.name.kind === 71 /* Identifier */ && param.name.escapedText === parameter.escapedText) {
+                        return i;
+                    }
+                }
+            }
+            return -1;
+        }
+        function checkTypePredicate(node) {
+            var parent = getTypePredicateParent(node);
+            if (!parent) {
+                // The parent must not be valid.
+                error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
+                return;
+            }
+            var typePredicate = getSignatureFromDeclaration(parent).typePredicate;
+            if (!typePredicate) {
+                return;
+            }
+            checkSourceElement(node.type);
+            var parameterName = node.parameterName;
+            if (ts.isThisTypePredicate(typePredicate)) {
+                getTypeFromThisTypeNode(parameterName);
+            }
+            else {
+                if (typePredicate.parameterIndex >= 0) {
+                    if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
+                        error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
+                    }
+                    else {
+                        var leadingError = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type);
+                        checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, 
+                        /*headMessage*/ undefined, leadingError);
+                    }
+                }
+                else if (parameterName) {
+                    var hasReportedError = false;
+                    for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) {
+                        var name = _a[_i].name;
+                        if (ts.isBindingPattern(name) &&
+                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) {
+                            hasReportedError = true;
+                            break;
+                        }
+                    }
+                    if (!hasReportedError) {
+                        error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
+                    }
+                }
+            }
+        }
+        function getTypePredicateParent(node) {
+            switch (node.parent.kind) {
+                case 187 /* ArrowFunction */:
+                case 155 /* CallSignature */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 160 /* FunctionType */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                    var parent = node.parent;
+                    if (node === parent.type) {
+                        return parent;
+                    }
+            }
+        }
+        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
+            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
+                var element = _a[_i];
+                if (ts.isOmittedExpression(element)) {
+                    continue;
+                }
+                var name = element.name;
+                if (name.kind === 71 /* Identifier */ && name.escapedText === predicateVariableName) {
+                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
+                    return true;
+                }
+                else if (name.kind === 175 /* ArrayBindingPattern */ || name.kind === 174 /* ObjectBindingPattern */) {
+                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        function checkSignatureDeclaration(node) {
+            // Grammar checking
+            if (node.kind === 157 /* IndexSignature */) {
+                checkGrammarIndexSignature(node);
+            }
+            else if (node.kind === 160 /* FunctionType */ || node.kind === 228 /* FunctionDeclaration */ || node.kind === 161 /* ConstructorType */ ||
+                node.kind === 155 /* CallSignature */ || node.kind === 152 /* Constructor */ ||
+                node.kind === 156 /* ConstructSignature */) {
+                checkGrammarFunctionLikeDeclaration(node);
+            }
+            var functionFlags = ts.getFunctionFlags(node);
+            if (!(functionFlags & 4 /* Invalid */)) {
+                // Async generators prior to ESNext require the __await and __asyncGenerator helpers
+                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 5 /* ESNext */) {
+                    checkExternalEmitHelpers(node, 6144 /* AsyncGeneratorIncludes */);
+                }
+                // Async functions prior to ES2017 require the __awaiter helper
+                if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) {
+                    checkExternalEmitHelpers(node, 64 /* Awaiter */);
+                }
+                // Generator functions, Async functions, and Async Generator functions prior to
+                // ES2015 require the __generator helper
+                if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) {
+                    checkExternalEmitHelpers(node, 128 /* Generator */);
+                }
+            }
+            checkTypeParameters(node.typeParameters);
+            ts.forEach(node.parameters, checkParameter);
+            // TODO(rbuckton): Should we start checking JSDoc types?
+            if (node.type) {
+                checkSourceElement(node.type);
+            }
+            if (produceDiagnostics) {
+                checkCollisionWithArgumentsInGeneratedCode(node);
+                var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
+                if (noImplicitAny && !returnTypeNode) {
+                    switch (node.kind) {
+                        case 156 /* ConstructSignature */:
+                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
+                            break;
+                        case 155 /* CallSignature */:
+                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
+                            break;
+                    }
+                }
+                if (returnTypeNode) {
+                    var functionFlags_1 = ts.getFunctionFlags(node);
+                    if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) {
+                        var returnType = getTypeFromTypeNode(returnTypeNode);
+                        if (returnType === voidType) {
+                            error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
+                        }
+                        else {
+                            var generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType;
+                            var iterableIteratorInstantiation = functionFlags_1 & 2 /* Async */
+                                ? createAsyncIterableIteratorType(generatorElementType) // AsyncGenerator function
+                                : createIterableIteratorType(generatorElementType); // Generator function
+                            // Naively, one could check that IterableIterator<any> is assignable to the return type annotation.
+                            // However, that would not catch the error in the following case.
+                            //
+                            //    interface BadGenerator extends Iterable<number>, Iterator<string> { }
+                            //    function* g(): BadGenerator { } // Iterable and Iterator have different types!
+                            //
+                            checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode);
+                        }
+                    }
+                    else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) {
+                        checkAsyncFunctionReturnType(node);
+                    }
+                }
+                if (noUnusedIdentifiers && !node.body) {
+                    checkUnusedTypeParameters(node);
+                }
+            }
+        }
+        function checkClassForDuplicateDeclarations(node) {
+            var Declaration;
+            (function (Declaration) {
+                Declaration[Declaration["Getter"] = 1] = "Getter";
+                Declaration[Declaration["Setter"] = 2] = "Setter";
+                Declaration[Declaration["Method"] = 4] = "Method";
+                Declaration[Declaration["Property"] = 3] = "Property";
+            })(Declaration || (Declaration = {}));
+            var instanceNames = ts.createUnderscoreEscapedMap();
+            var staticNames = ts.createUnderscoreEscapedMap();
+            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                var member = _a[_i];
+                if (member.kind === 152 /* Constructor */) {
+                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
+                        var param = _c[_b];
+                        if (ts.isParameterPropertyDeclaration(param) && !ts.isBindingPattern(param.name)) {
+                            addName(instanceNames, param.name, param.name.escapedText, 3 /* Property */);
+                        }
+                    }
+                }
+                else {
+                    var isStatic = ts.hasModifier(member, 32 /* Static */);
+                    var names = isStatic ? staticNames : instanceNames;
+                    var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name);
+                    if (memberName) {
+                        switch (member.kind) {
+                            case 153 /* GetAccessor */:
+                                addName(names, member.name, memberName, 1 /* Getter */);
+                                break;
+                            case 154 /* SetAccessor */:
+                                addName(names, member.name, memberName, 2 /* Setter */);
+                                break;
+                            case 149 /* PropertyDeclaration */:
+                                addName(names, member.name, memberName, 3 /* Property */);
+                                break;
+                            case 151 /* MethodDeclaration */:
+                                addName(names, member.name, memberName, 4 /* Method */);
+                                break;
+                        }
+                    }
+                }
+            }
+            function addName(names, location, name, meaning) {
+                var prev = names.get(name);
+                if (prev) {
+                    if (prev & 4 /* Method */) {
+                        if (meaning !== 4 /* Method */) {
+                            error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
+                        }
+                    }
+                    else if (prev & meaning) {
+                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
+                    }
+                    else {
+                        names.set(name, prev | meaning);
+                    }
+                }
+                else {
+                    names.set(name, meaning);
+                }
+            }
+        }
+        /**
+         * Static members being set on a constructor function may conflict with built-in properties
+         * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
+         * built-in properties. This check issues a transpile error when a class has a static
+         * member with the same name as a non-writable built-in property.
+         *
+         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
+         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
+         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
+         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances
+         */
+        function checkClassForStaticPropertyNameConflicts(node) {
+            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                var member = _a[_i];
+                var memberNameNode = member.name;
+                var isStatic = ts.hasModifier(member, 32 /* Static */);
+                if (isStatic && memberNameNode) {
+                    var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode);
+                    switch (memberName) {
+                        case "name":
+                        case "length":
+                        case "caller":
+                        case "arguments":
+                        case "prototype":
+                            var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
+                            var className = getNameOfSymbol(getSymbolOfNode(node));
+                            error(memberNameNode, message, memberName, className);
+                            break;
+                    }
+                }
+            }
+        }
+        function checkObjectTypeForDuplicateDeclarations(node) {
+            var names = ts.createMap();
+            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                var member = _a[_i];
+                if (member.kind === 148 /* PropertySignature */) {
+                    var memberName = void 0;
+                    switch (member.name.kind) {
+                        case 9 /* StringLiteral */:
+                        case 8 /* NumericLiteral */:
+                            memberName = member.name.text;
+                            break;
+                        case 71 /* Identifier */:
+                            memberName = ts.idText(member.name);
+                            break;
+                        default:
+                            continue;
+                    }
+                    if (names.get(memberName)) {
+                        error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName);
+                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
+                    }
+                    else {
+                        names.set(memberName, true);
+                    }
+                }
+            }
+        }
+        function checkTypeForDuplicateIndexSignatures(node) {
+            if (node.kind === 230 /* InterfaceDeclaration */) {
+                var nodeSymbol = getSymbolOfNode(node);
+                // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
+                // to prevent this run check only for the first declaration of a given kind
+                if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
+                    return;
+                }
+            }
+            // TypeScript 1.0 spec (April 2014)
+            // 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
+            // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
+            var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
+            if (indexSymbol) {
+                var seenNumericIndexer = false;
+                var seenStringIndexer = false;
+                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    var declaration = decl;
+                    if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
+                        switch (declaration.parameters[0].type.kind) {
+                            case 136 /* StringKeyword */:
+                                if (!seenStringIndexer) {
+                                    seenStringIndexer = true;
+                                }
+                                else {
+                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
+                                }
+                                break;
+                            case 133 /* NumberKeyword */:
+                                if (!seenNumericIndexer) {
+                                    seenNumericIndexer = true;
+                                }
+                                else {
+                                    error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
+                                }
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+        function checkPropertyDeclaration(node) {
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
+            checkVariableLikeDeclaration(node);
+        }
+        function checkMethodDeclaration(node) {
+            // Grammar checking
+            checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name);
+            // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
+            checkFunctionOrMethodDeclaration(node);
+            // Abstract methods cannot have an implementation.
+            // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
+            if (ts.hasModifier(node, 128 /* Abstract */) && node.body) {
+                error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name));
+            }
+        }
+        function checkConstructorDeclaration(node) {
+            // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
+            checkSignatureDeclaration(node);
+            // Grammar check for checking only related to constructorDeclaration
+            checkGrammarConstructorTypeParameters(node) || checkGrammarConstructorTypeAnnotation(node);
+            checkSourceElement(node.body);
+            registerForUnusedIdentifiersCheck(node);
+            var symbol = getSymbolOfNode(node);
+            var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind);
+            // Only type check the symbol once
+            if (node === firstDeclaration) {
+                checkFunctionOrConstructorSymbol(symbol);
+            }
+            // exit early in the case of signature - super checks are not relevant to them
+            if (ts.nodeIsMissing(node.body)) {
+                return;
+            }
+            if (!produceDiagnostics) {
+                return;
+            }
+            function containsSuperCallAsComputedPropertyName(n) {
+                var name = ts.getNameOfDeclaration(n);
+                return name && containsSuperCall(name);
+            }
+            function containsSuperCall(n) {
+                if (ts.isSuperCall(n)) {
+                    return true;
+                }
+                else if (ts.isFunctionLike(n)) {
+                    return false;
+                }
+                else if (ts.isClassLike(n)) {
+                    return ts.forEach(n.members, containsSuperCallAsComputedPropertyName);
+                }
+                return ts.forEachChild(n, containsSuperCall);
+            }
+            function isInstancePropertyWithInitializer(n) {
+                return n.kind === 149 /* PropertyDeclaration */ &&
+                    !ts.hasModifier(n, 32 /* Static */) &&
+                    !!n.initializer;
+            }
+            // TS 1.0 spec (April 2014): 8.3.2
+            // Constructors of classes with no extends clause may not contain super calls, whereas
+            // constructors of derived classes must contain at least one super call somewhere in their function body.
+            var containingClassDecl = node.parent;
+            if (ts.getClassExtendsHeritageClauseElement(containingClassDecl)) {
+                captureLexicalThis(node.parent, containingClassDecl);
+                var classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
+                var superCall = getSuperCallInConstructor(node);
+                if (superCall) {
+                    if (classExtendsNull) {
+                        error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
+                    }
+                    // The first statement in the body of a constructor (excluding prologue directives) must be a super call
+                    // if both of the following are true:
+                    // - The containing class is a derived class.
+                    // - The constructor declares parameter properties
+                    //   or the containing class declares instance member variables with initializers.
+                    var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) ||
+                        ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); });
+                    // Skip past any prologue directives to find the first statement
+                    // to ensure that it was a super call.
+                    if (superCallShouldBeFirst) {
+                        var statements = node.body.statements;
+                        var superCallStatement = void 0;
+                        for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) {
+                            var statement = statements_2[_i];
+                            if (statement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
+                                superCallStatement = statement;
+                                break;
+                            }
+                            if (!ts.isPrologueDirective(statement)) {
+                                break;
+                            }
+                        }
+                        if (!superCallStatement) {
+                            error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
+                        }
+                    }
+                }
+                else if (!classExtendsNull) {
+                    error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
+                }
+            }
+        }
+        function checkAccessorDeclaration(node) {
+            if (produceDiagnostics) {
+                // Grammar checking accessors
+                checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
+                checkDecorators(node);
+                checkSignatureDeclaration(node);
+                if (node.kind === 153 /* GetAccessor */) {
+                    if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 128 /* HasImplicitReturn */)) {
+                        if (!(node.flags & 256 /* HasExplicitReturn */)) {
+                            error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value);
+                        }
+                    }
+                }
+                // Do not use hasDynamicName here, because that returns false for well known symbols.
+                // We want to perform checkComputedPropertyName for all computed properties, including
+                // well known symbols.
+                if (node.name.kind === 144 /* ComputedPropertyName */) {
+                    checkComputedPropertyName(node.name);
+                }
+                if (!ts.hasDynamicName(node)) {
+                    // TypeScript 1.0 spec (April 2014): 8.4.3
+                    // Accessors for the same member name must specify the same accessibility.
+                    var otherKind = node.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */;
+                    var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind);
+                    if (otherAccessor) {
+                        var nodeFlags = ts.getModifierFlags(node);
+                        var otherFlags = ts.getModifierFlags(otherAccessor);
+                        if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) {
+                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
+                        }
+                        if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) {
+                            error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
+                        }
+                        // TypeScript 1.0 spec (April 2014): 4.5
+                        // If both accessors include type annotations, the specified types must be identical.
+                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
+                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
+                    }
+                }
+                var returnType = getTypeOfAccessors(getSymbolOfNode(node));
+                if (node.kind === 153 /* GetAccessor */) {
+                    checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
+                }
+            }
+            checkSourceElement(node.body);
+            registerForUnusedIdentifiersCheck(node);
+        }
+        function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) {
+            var firstType = getAnnotatedType(first);
+            var secondType = getAnnotatedType(second);
+            if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
+                error(first, message);
+            }
+        }
+        function checkMissingDeclaration(node) {
+            checkDecorators(node);
+        }
+        function checkTypeArgumentConstraints(typeParameters, typeArgumentNodes) {
+            var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
+            var typeArguments;
+            var mapper;
+            var result = true;
+            for (var i = 0; i < typeParameters.length; i++) {
+                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
+                if (constraint) {
+                    if (!typeArguments) {
+                        typeArguments = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, ts.isInJavaScriptFile(typeArgumentNodes[i]));
+                        mapper = createTypeMapper(typeParameters, typeArguments);
+                    }
+                    var typeArgument = typeArguments[i];
+                    result = result && checkTypeAssignableTo(typeArgument, instantiateType(constraint, mapper), typeArgumentNodes[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
+                }
+            }
+            return result;
+        }
+        function checkTypeReferenceNode(node) {
+            checkGrammarTypeArguments(node, node.typeArguments);
+            if (node.kind === 159 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJavaScriptFile(node) && !ts.isInJSDoc(node)) {
+                grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
+            }
+            var type = getTypeFromTypeReference(node);
+            if (type !== unknownType) {
+                if (node.typeArguments) {
+                    // Do type argument local checks only if referenced type is successfully resolved
+                    ts.forEach(node.typeArguments, checkSourceElement);
+                    if (produceDiagnostics) {
+                        var symbol = getNodeLinks(node).resolvedSymbol;
+                        if (!symbol) {
+                            // There is no resolved symbol cached if the type resolved to a builtin
+                            // via JSDoc type reference resolution (eg, Boolean became boolean), none
+                            // of which are generic when they have no associated symbol
+                            // (additionally, JSDoc's index signature syntax, Object<string, T> actually uses generic syntax without being generic)
+                            if (!ts.isJSDocIndexSignature(node)) {
+                                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
+                            }
+                            return;
+                        }
+                        var typeParameters = symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters;
+                        if (!typeParameters && getObjectFlags(type) & 4 /* Reference */) {
+                            typeParameters = type.target.localTypeParameters;
+                        }
+                        checkTypeArgumentConstraints(typeParameters, node.typeArguments);
+                    }
+                }
+                if (type.flags & 16 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) {
+                    error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
+                }
+            }
+        }
+        function checkTypeQuery(node) {
+            getTypeFromTypeQueryNode(node);
+        }
+        function checkTypeLiteral(node) {
+            ts.forEach(node.members, checkSourceElement);
+            if (produceDiagnostics) {
+                var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
+                checkIndexConstraints(type);
+                checkTypeForDuplicateIndexSignatures(node);
+                checkObjectTypeForDuplicateDeclarations(node);
+            }
+        }
+        function checkArrayType(node) {
+            checkSourceElement(node.elementType);
+        }
+        function checkTupleType(node) {
+            // Grammar checking
+            var hasErrorFromDisallowedTrailingComma = checkGrammarForDisallowedTrailingComma(node.elementTypes);
+            if (!hasErrorFromDisallowedTrailingComma && node.elementTypes.length === 0) {
+                grammarErrorOnNode(node, ts.Diagnostics.A_tuple_type_element_list_cannot_be_empty);
+            }
+            ts.forEach(node.elementTypes, checkSourceElement);
+        }
+        function checkUnionOrIntersectionType(node) {
+            ts.forEach(node.types, checkSourceElement);
+        }
+        function checkIndexedAccessIndexType(type, accessNode) {
+            if (!(type.flags & 524288 /* IndexedAccess */)) {
+                return type;
+            }
+            // Check if the index type is assignable to 'keyof T' for the object type.
+            var objectType = type.objectType;
+            var indexType = type.indexType;
+            if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
+                if (accessNode.kind === 180 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) &&
+                    getObjectFlags(objectType) & 32 /* Mapped */ && objectType.declaration.readonlyToken) {
+                    error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
+                }
+                return type;
+            }
+            // Check if we're indexing with a numeric type and if either object or index types
+            // is a generic type with a constraint that has a numeric index signature.
+            if (getIndexInfoOfType(getApparentType(objectType), 1 /* Number */) && isTypeAssignableToKind(indexType, 84 /* NumberLike */)) {
+                return type;
+            }
+            error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
+            return type;
+        }
+        function checkIndexedAccessType(node) {
+            checkSourceElement(node.objectType);
+            checkSourceElement(node.indexType);
+            checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node);
+        }
+        function checkMappedType(node) {
+            checkSourceElement(node.typeParameter);
+            checkSourceElement(node.type);
+            var type = getTypeFromMappedTypeNode(node);
+            var constraintType = getConstraintTypeFromMappedType(type);
+            checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint);
+        }
+        function isPrivateWithinAmbient(node) {
+            return ts.hasModifier(node, 8 /* Private */) && ts.isInAmbientContext(node);
+        }
+        function getEffectiveDeclarationFlags(n, flagsToCheck) {
+            var flags = ts.getCombinedModifierFlags(n);
+            // children of classes (even ambient classes) should not be marked as ambient or export
+            // because those flags have no useful semantics there.
+            if (n.parent.kind !== 230 /* InterfaceDeclaration */ &&
+                n.parent.kind !== 229 /* ClassDeclaration */ &&
+                n.parent.kind !== 199 /* ClassExpression */ &&
+                ts.isInAmbientContext(n)) {
+                if (!(flags & 2 /* Ambient */)) {
+                    // It is nested in an ambient context, which means it is automatically exported
+                    flags |= 1 /* Export */;
+                }
+                flags |= 2 /* Ambient */;
+            }
+            return flags & flagsToCheck;
+        }
+        function checkFunctionOrConstructorSymbol(symbol) {
+            if (!produceDiagnostics) {
+                return;
+            }
+            function getCanonicalOverload(overloads, implementation) {
+                // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
+                // Error on all deviations from this canonical set of flags
+                // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
+                // report the errors on those. To achieve this, we will say that the implementation is
+                // the canonical signature only if it is in the same container as the first overload
+                var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
+                return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
+            }
+            function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
+                // Error if some overloads have a flag that is not shared by all overloads. To find the
+                // deviations, we XOR someOverloadFlags with allOverloadFlags
+                var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
+                if (someButNotAllOverloadFlags !== 0) {
+                    var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
+                    ts.forEach(overloads, function (o) {
+                        var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1;
+                        if (deviation & 1 /* Export */) {
+                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
+                        }
+                        else if (deviation & 2 /* Ambient */) {
+                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
+                        }
+                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
+                            error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
+                        }
+                        else if (deviation & 128 /* Abstract */) {
+                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
+                        }
+                    });
+                }
+            }
+            function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) {
+                if (someHaveQuestionToken !== allHaveQuestionToken) {
+                    var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation));
+                    ts.forEach(overloads, function (o) {
+                        var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1;
+                        if (deviation) {
+                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
+                        }
+                    });
+                }
+            }
+            var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */;
+            var someNodeFlags = 0 /* None */;
+            var allNodeFlags = flagsToCheck;
+            var someHaveQuestionToken = false;
+            var allHaveQuestionToken = true;
+            var hasOverloads = false;
+            var bodyDeclaration;
+            var lastSeenNonAmbientDeclaration;
+            var previousDeclaration;
+            var declarations = symbol.declarations;
+            var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
+            function reportImplementationExpectedError(node) {
+                if (node.name && ts.nodeIsMissing(node.name)) {
+                    return;
+                }
+                var seen = false;
+                var subsequentNode = ts.forEachChild(node.parent, function (c) {
+                    if (seen) {
+                        return c;
+                    }
+                    else {
+                        seen = c === node;
+                    }
+                });
+                // We may be here because of some extra nodes between overloads that could not be parsed into a valid node.
+                // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
+                if (subsequentNode && subsequentNode.pos === node.end) {
+                    if (subsequentNode.kind === node.kind) {
+                        var errorNode_1 = subsequentNode.name || subsequentNode;
+                        // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
+                        var subsequentName = subsequentNode.name;
+                        if (node.name && subsequentName &&
+                            (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) ||
+                                !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) {
+                            var reportError = (node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */) &&
+                                ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */);
+                            // we can get here in two cases
+                            // 1. mixed static and instance class members
+                            // 2. something with the same name was defined before the set of overloads that prevents them from merging
+                            // here we'll report error only for the first case since for second we should already report error in binder
+                            if (reportError) {
+                                var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
+                                error(errorNode_1, diagnostic);
+                            }
+                            return;
+                        }
+                        else if (ts.nodeIsPresent(subsequentNode.body)) {
+                            error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
+                            return;
+                        }
+                    }
+                }
+                var errorNode = node.name || node;
+                if (isConstructor) {
+                    error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
+                }
+                else {
+                    // Report different errors regarding non-consecutive blocks of declarations depending on whether
+                    // the node in question is abstract.
+                    if (ts.hasModifier(node, 128 /* Abstract */)) {
+                        error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
+                    }
+                    else {
+                        error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
+                    }
+                }
+            }
+            var duplicateFunctionDeclaration = false;
+            var multipleConstructorImplementation = false;
+            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
+                var current = declarations_4[_i];
+                var node = current;
+                var inAmbientContext = ts.isInAmbientContext(node);
+                var inAmbientContextOrInterface = node.parent.kind === 230 /* InterfaceDeclaration */ || node.parent.kind === 163 /* TypeLiteral */ || inAmbientContext;
+                if (inAmbientContextOrInterface) {
+                    // check if declarations are consecutive only if they are non-ambient
+                    // 1. ambient declarations can be interleaved
+                    // i.e. this is legal
+                    //     declare function foo();
+                    //     declare function bar();
+                    //     declare function foo();
+                    // 2. mixing ambient and non-ambient declarations is a separate error that will be reported - do not want to report an extra one
+                    previousDeclaration = undefined;
+                }
+                if (node.kind === 228 /* FunctionDeclaration */ || node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */ || node.kind === 152 /* Constructor */) {
+                    var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
+                    someNodeFlags |= currentNodeFlags;
+                    allNodeFlags &= currentNodeFlags;
+                    someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node);
+                    allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node);
+                    if (ts.nodeIsPresent(node.body) && bodyDeclaration) {
+                        if (isConstructor) {
+                            multipleConstructorImplementation = true;
+                        }
+                        else {
+                            duplicateFunctionDeclaration = true;
+                        }
+                    }
+                    else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
+                        reportImplementationExpectedError(previousDeclaration);
+                    }
+                    if (ts.nodeIsPresent(node.body)) {
+                        if (!bodyDeclaration) {
+                            bodyDeclaration = node;
+                        }
+                    }
+                    else {
+                        hasOverloads = true;
+                    }
+                    previousDeclaration = node;
+                    if (!inAmbientContextOrInterface) {
+                        lastSeenNonAmbientDeclaration = node;
+                    }
+                }
+            }
+            if (multipleConstructorImplementation) {
+                ts.forEach(declarations, function (declaration) {
+                    error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
+                });
+            }
+            if (duplicateFunctionDeclaration) {
+                ts.forEach(declarations, function (declaration) {
+                    error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation);
+                });
+            }
+            // Abstract methods can't have an implementation -- in particular, they don't need one.
+            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
+                !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) {
+                reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
+            }
+            if (hasOverloads) {
+                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
+                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
+                if (bodyDeclaration) {
+                    var signatures = getSignaturesOfSymbol(symbol);
+                    var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
+                    for (var _a = 0, signatures_7 = signatures; _a < signatures_7.length; _a++) {
+                        var signature = signatures_7[_a];
+                        if (!isImplementationCompatibleWithOverload(bodySignature, signature)) {
+                            error(signature.declaration, ts.Diagnostics.Overload_signature_is_not_compatible_with_function_implementation);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        function checkExportsOnMergedDeclarations(node) {
+            if (!produceDiagnostics) {
+                return;
+            }
+            // if localSymbol is defined on node then node itself is exported - check is required
+            var symbol = node.localSymbol;
+            if (!symbol) {
+                // local symbol is undefined => this declaration is non-exported.
+                // however symbol might contain other declarations that are exported
+                symbol = getSymbolOfNode(node);
+                if (!symbol.exportSymbol) {
+                    // this is a pure local symbol (all declarations are non-exported) - no need to check anything
+                    return;
+                }
+            }
+            // run the check only for the first declaration in the list
+            if (ts.getDeclarationOfKind(symbol, node.kind) !== node) {
+                return;
+            }
+            var exportedDeclarationSpaces = 0 /* None */;
+            var nonExportedDeclarationSpaces = 0 /* None */;
+            var defaultExportedDeclarationSpaces = 0 /* None */;
+            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                var d = _a[_i];
+                var declarationSpaces = getDeclarationSpaces(d);
+                var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */);
+                if (effectiveDeclarationFlags & 1 /* Export */) {
+                    if (effectiveDeclarationFlags & 512 /* Default */) {
+                        defaultExportedDeclarationSpaces |= declarationSpaces;
+                    }
+                    else {
+                        exportedDeclarationSpaces |= declarationSpaces;
+                    }
+                }
+                else {
+                    nonExportedDeclarationSpaces |= declarationSpaces;
+                }
+            }
+            // Spaces for anything not declared a 'default export'.
+            var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
+            var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
+            var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
+            if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
+                // declaration spaces for exported and non-exported declarations intersect
+                for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) {
+                    var d = _c[_b];
+                    var declarationSpaces = getDeclarationSpaces(d);
+                    var name = ts.getNameOfDeclaration(d);
+                    // Only error on the declarations that contributed to the intersecting spaces.
+                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
+                        error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name));
+                    }
+                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
+                        error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name));
+                    }
+                }
+            }
+            var DeclarationSpaces;
+            (function (DeclarationSpaces) {
+                DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None";
+                DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue";
+                DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType";
+                DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace";
+            })(DeclarationSpaces || (DeclarationSpaces = {}));
+            function getDeclarationSpaces(d) {
+                switch (d.kind) {
+                    case 230 /* InterfaceDeclaration */:
+                    case 231 /* TypeAliasDeclaration */:
+                    // A jsdoc typedef is, by definition, a type alias
+                    case 283 /* JSDocTypedefTag */:
+                        return 2 /* ExportType */;
+                    case 233 /* ModuleDeclaration */:
+                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
+                            ? 4 /* ExportNamespace */ | 1 /* ExportValue */
+                            : 4 /* ExportNamespace */;
+                    case 229 /* ClassDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                        return 2 /* ExportType */ | 1 /* ExportValue */;
+                    // The below options all declare an Alias, which is allowed to merge with other values within the importing module
+                    case 237 /* ImportEqualsDeclaration */:
+                    case 240 /* NamespaceImport */:
+                    case 239 /* ImportClause */:
+                        var result_3 = 0 /* None */;
+                        var target = resolveAlias(getSymbolOfNode(d));
+                        ts.forEach(target.declarations, function (d) { result_3 |= getDeclarationSpaces(d); });
+                        return result_3;
+                    case 226 /* VariableDeclaration */:
+                    case 176 /* BindingElement */:
+                    case 228 /* FunctionDeclaration */:
+                    case 242 /* ImportSpecifier */:// https://github.com/Microsoft/TypeScript/pull/7591
+                        return 1 /* ExportValue */;
+                    default:
+                        ts.Debug.fail(ts.SyntaxKind[d.kind]);
+                }
+            }
+        }
+        function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage) {
+            var promisedType = getPromisedTypeOfPromise(type, errorNode);
+            return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage);
+        }
+        /**
+         * Gets the "promised type" of a promise.
+         * @param type The type of the promise.
+         * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
+         */
+        function getPromisedTypeOfPromise(promise, errorNode) {
+            //
+            //  { // promise
+            //      then( // thenFunction
+            //          onfulfilled: ( // onfulfilledParameterType
+            //              value: T // valueParameterType
+            //          ) => any
+            //      ): any;
+            //  }
+            //
+            if (isTypeAny(promise)) {
+                return undefined;
+            }
+            var typeAsPromise = promise;
+            if (typeAsPromise.promisedTypeOfPromise) {
+                return typeAsPromise.promisedTypeOfPromise;
+            }
+            if (isReferenceToType(promise, getGlobalPromiseType(/*reportErrors*/ false))) {
+                return typeAsPromise.promisedTypeOfPromise = promise.typeArguments[0];
+            }
+            var thenFunction = getTypeOfPropertyOfType(promise, "then");
+            if (isTypeAny(thenFunction)) {
+                return undefined;
+            }
+            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray;
+            if (thenSignatures.length === 0) {
+                if (errorNode) {
+                    error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method);
+                }
+                return undefined;
+            }
+            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 524288 /* NEUndefinedOrNull */);
+            if (isTypeAny(onfulfilledParameterType)) {
+                return undefined;
+            }
+            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
+            if (onfulfilledParameterSignatures.length === 0) {
+                if (errorNode) {
+                    error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback);
+                }
+                return undefined;
+            }
+            return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), /*subtypeReduction*/ true);
+        }
+        /**
+         * Gets the "awaited type" of a type.
+         * @param type The type to await.
+         * @remarks The "awaited type" of an expression is its "promised type" if the expression is a
+         * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
+         * The runtime behavior of the `await` keyword.
+         */
+        function checkAwaitedType(type, errorNode, diagnosticMessage) {
+            return getAwaitedType(type, errorNode, diagnosticMessage) || unknownType;
+        }
+        function getAwaitedType(type, errorNode, diagnosticMessage) {
+            var typeAsAwaitable = type;
+            if (typeAsAwaitable.awaitedTypeOfType) {
+                return typeAsAwaitable.awaitedTypeOfType;
+            }
+            if (isTypeAny(type)) {
+                return typeAsAwaitable.awaitedTypeOfType = type;
+            }
+            if (type.flags & 65536 /* Union */) {
+                var types = void 0;
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var constituentType = _a[_i];
+                    types = ts.append(types, getAwaitedType(constituentType, errorNode, diagnosticMessage));
+                }
+                if (!types) {
+                    return undefined;
+                }
+                return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
+            }
+            var promisedType = getPromisedTypeOfPromise(type);
+            if (promisedType) {
+                if (type.id === promisedType.id || ts.indexOf(awaitedTypeStack, promisedType.id) >= 0) {
+                    // Verify that we don't have a bad actor in the form of a promise whose
+                    // promised type is the same as the promise type, or a mutually recursive
+                    // promise. If so, we return undefined as we cannot guess the shape. If this
+                    // were the actual case in the JavaScript, this Promise would never resolve.
+                    //
+                    // An example of a bad actor with a singly-recursive promise type might
+                    // be:
+                    //
+                    //  interface BadPromise {
+                    //      then(
+                    //          onfulfilled: (value: BadPromise) => any,
+                    //          onrejected: (error: any) => any): BadPromise;
+                    //  }
+                    // The above interface will pass the PromiseLike check, and return a
+                    // promised type of `BadPromise`. Since this is a self reference, we
+                    // don't want to keep recursing ad infinitum.
+                    //
+                    // An example of a bad actor in the form of a mutually-recursive
+                    // promise type might be:
+                    //
+                    //  interface BadPromiseA {
+                    //      then(
+                    //          onfulfilled: (value: BadPromiseB) => any,
+                    //          onrejected: (error: any) => any): BadPromiseB;
+                    //  }
+                    //
+                    //  interface BadPromiseB {
+                    //      then(
+                    //          onfulfilled: (value: BadPromiseA) => any,
+                    //          onrejected: (error: any) => any): BadPromiseA;
+                    //  }
+                    //
+                    if (errorNode) {
+                        error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
+                    }
+                    return undefined;
+                }
+                // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
+                // See the comments above for more information.
+                awaitedTypeStack.push(type.id);
+                var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage);
+                awaitedTypeStack.pop();
+                if (!awaitedType) {
+                    return undefined;
+                }
+                return typeAsAwaitable.awaitedTypeOfType = awaitedType;
+            }
+            // The type was not a promise, so it could not be unwrapped any further.
+            // As long as the type does not have a callable "then" property, it is
+            // safe to return the type; otherwise, an error will be reported in
+            // the call to getNonThenableType and we will return undefined.
+            //
+            // An example of a non-promise "thenable" might be:
+            //
+            //  await { then(): void {} }
+            //
+            // The "thenable" does not match the minimal definition for a promise. When
+            // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
+            // will never settle. We treat this as an error to help flag an early indicator
+            // of a runtime problem. If the user wants to return this value from an async
+            // function, they would need to wrap it in some other value. If they want it to
+            // be treated as a promise, they can cast to <any>.
+            var thenFunction = getTypeOfPropertyOfType(type, "then");
+            if (thenFunction && getSignaturesOfType(thenFunction, 0 /* Call */).length > 0) {
+                if (errorNode) {
+                    ts.Debug.assert(!!diagnosticMessage);
+                    error(errorNode, diagnosticMessage);
+                }
+                return undefined;
+            }
+            return typeAsAwaitable.awaitedTypeOfType = type;
+        }
+        /**
+         * Checks the return type of an async function to ensure it is a compatible
+         * Promise implementation.
+         *
+         * This checks that an async function has a valid Promise-compatible return type,
+         * and returns the *awaited type* of the promise. An async function has a valid
+         * Promise-compatible return type if the resolved value of the return type has a
+         * construct signature that takes in an `initializer` function that in turn supplies
+         * a `resolve` function as one of its arguments and results in an object with a
+         * callable `then` signature.
+         *
+         * @param node The signature to check
+         */
+        function checkAsyncFunctionReturnType(node) {
+            // As part of our emit for an async function, we will need to emit the entity name of
+            // the return type annotation as an expression. To meet the necessary runtime semantics
+            // for __awaiter, we must also check that the type of the declaration (e.g. the static
+            // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
+            //
+            // An example might be (from lib.es6.d.ts):
+            //
+            //  interface Promise<T> { ... }
+            //  interface PromiseConstructor {
+            //      new <T>(...): Promise<T>;
+            //  }
+            //  declare var Promise: PromiseConstructor;
+            //
+            // When an async function declares a return type annotation of `Promise<T>`, we
+            // need to get the type of the `Promise` variable declaration above, which would
+            // be `PromiseConstructor`.
+            //
+            // The same case applies to a class:
+            //
+            //  declare class Promise<T> {
+            //      constructor(...);
+            //      then<U>(...): Promise<U>;
+            //  }
+            //
+            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
+            var returnType = getTypeFromTypeNode(returnTypeNode);
+            if (languageVersion >= 2 /* ES2015 */) {
+                if (returnType === unknownType) {
+                    return unknownType;
+                }
+                var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
+                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
+                    // The promise type was not a valid type reference to the global promise type, so we
+                    // report an error and return the unknown type.
+                    error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
+                    return unknownType;
+                }
+            }
+            else {
+                // Always mark the type node as referenced if it points to a value
+                markTypeNodeAsReferenced(returnTypeNode);
+                if (returnType === unknownType) {
+                    return unknownType;
+                }
+                var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode);
+                if (promiseConstructorName === undefined) {
+                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
+                    return unknownType;
+                }
+                var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 107455 /* Value */, /*ignoreErrors*/ true);
+                var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType;
+                if (promiseConstructorType === unknownType) {
+                    if (promiseConstructorName.kind === 71 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
+                        error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
+                    }
+                    else {
+                        error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
+                    }
+                    return unknownType;
+                }
+                var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true);
+                if (globalPromiseConstructorLikeType === emptyObjectType) {
+                    // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
+                    // compatibility with __awaiter.
+                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
+                    return unknownType;
+                }
+                if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
+                    return unknownType;
+                }
+                // Verify there is no local declaration that could collide with the promise constructor.
+                var rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName);
+                var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 107455 /* Value */);
+                if (collidingSymbol) {
+                    error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName));
+                    return unknownType;
+                }
+            }
+            // Get and return the awaited type of the return type.
+            return checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+        }
+        /** Check a decorator */
+        function checkDecorator(node) {
+            var signature = getResolvedSignature(node);
+            var returnType = getReturnTypeOfSignature(signature);
+            if (returnType.flags & 1 /* Any */) {
+                return;
+            }
+            var expectedReturnType;
+            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
+            var errorInfo;
+            switch (node.parent.kind) {
+                case 229 /* ClassDeclaration */:
+                    var classSymbol = getSymbolOfNode(node.parent);
+                    var classConstructorType = getTypeOfSymbol(classSymbol);
+                    expectedReturnType = getUnionType([classConstructorType, voidType]);
+                    break;
+                case 146 /* Parameter */:
+                    expectedReturnType = voidType;
+                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
+                    break;
+                case 149 /* PropertyDeclaration */:
+                    expectedReturnType = voidType;
+                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
+                    break;
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    var methodType = getTypeOfNode(node.parent);
+                    var descriptorType = createTypedPropertyDescriptorType(methodType);
+                    expectedReturnType = getUnionType([descriptorType, voidType]);
+                    break;
+            }
+            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, errorInfo);
+        }
+        /**
+         * If a TypeNode can be resolved to a value symbol imported from an external module, it is
+         * marked as referenced to prevent import elision.
+         */
+        function markTypeNodeAsReferenced(node) {
+            markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node));
+        }
+        function markEntityNameOrEntityExpressionAsReference(typeName) {
+            if (!typeName)
+                return;
+            var rootName = getFirstIdentifier(typeName);
+            var meaning = (typeName.kind === 71 /* Identifier */ ? 793064 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */;
+            var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true);
+            if (rootSymbol
+                && rootSymbol.flags & 2097152 /* Alias */
+                && symbolIsValue(rootSymbol)
+                && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
+                markAliasSymbolAsReferenced(rootSymbol);
+            }
+        }
+        /**
+         * This function marks the type used for metadata decorator as referenced if it is import
+         * from external module.
+         * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
+         * union and intersection type
+         * @param node
+         */
+        function markDecoratorMedataDataTypeNodeAsReferenced(node) {
+            var entityName = getEntityNameForDecoratorMetadata(node);
+            if (entityName && ts.isEntityName(entityName)) {
+                markEntityNameOrEntityExpressionAsReference(entityName);
+            }
+        }
+        function getEntityNameForDecoratorMetadata(node) {
+            if (node) {
+                switch (node.kind) {
+                    case 167 /* IntersectionType */:
+                    case 166 /* UnionType */:
+                        var commonEntityName = void 0;
+                        for (var _i = 0, _a = node.types; _i < _a.length; _i++) {
+                            var typeNode = _a[_i];
+                            var individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
+                            if (!individualEntityName) {
+                                // Individual is something like string number
+                                // So it would be serialized to either that type or object
+                                // Safe to return here
+                                return undefined;
+                            }
+                            if (commonEntityName) {
+                                // Note this is in sync with the transformation that happens for type node.
+                                // Keep this in sync with serializeUnionOrIntersectionType
+                                // Verify if they refer to same entity and is identifier
+                                // return undefined if they dont match because we would emit object
+                                if (!ts.isIdentifier(commonEntityName) ||
+                                    !ts.isIdentifier(individualEntityName) ||
+                                    commonEntityName.escapedText !== individualEntityName.escapedText) {
+                                    return undefined;
+                                }
+                            }
+                            else {
+                                commonEntityName = individualEntityName;
+                            }
+                        }
+                        return commonEntityName;
+                    case 168 /* ParenthesizedType */:
+                        return getEntityNameForDecoratorMetadata(node.type);
+                    case 159 /* TypeReference */:
+                        return node.typeName;
+                }
+            }
+        }
+        function getParameterTypeNodeForDecoratorCheck(node) {
+            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
+            return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode;
+        }
+        /** Check the decorators of a node */
+        function checkDecorators(node) {
+            if (!node.decorators) {
+                return;
+            }
+            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
+            // checkGrammarDecorators.
+            if (!ts.nodeCanBeDecorated(node)) {
+                return;
+            }
+            if (!compilerOptions.experimentalDecorators) {
+                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
+            }
+            var firstDecorator = node.decorators[0];
+            checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */);
+            if (node.kind === 146 /* Parameter */) {
+                checkExternalEmitHelpers(firstDecorator, 32 /* Param */);
+            }
+            if (compilerOptions.emitDecoratorMetadata) {
+                checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */);
+                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
+                switch (node.kind) {
+                    case 229 /* ClassDeclaration */:
+                        var constructor = ts.getFirstConstructorWithBody(node);
+                        if (constructor) {
+                            for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) {
+                                var parameter = _a[_i];
+                                markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+                            }
+                        }
+                        break;
+                    case 151 /* MethodDeclaration */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) {
+                            var parameter = _c[_b];
+                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+                        }
+                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node));
+                        break;
+                    case 149 /* PropertyDeclaration */:
+                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node));
+                        break;
+                    case 146 /* Parameter */:
+                        markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
+                        break;
+                }
+            }
+            ts.forEach(node.decorators, checkDecorator);
+        }
+        function checkFunctionDeclaration(node) {
+            if (produceDiagnostics) {
+                checkFunctionOrMethodDeclaration(node);
+                checkGrammarForGenerator(node);
+                checkCollisionWithCapturedSuperVariable(node, node.name);
+                checkCollisionWithCapturedThisVariable(node, node.name);
+                checkCollisionWithCapturedNewTargetVariable(node, node.name);
+                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+            }
+        }
+        function checkJSDocTypedefTag(node) {
+            if (!node.typeExpression) {
+                // If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
+                error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
+            }
+        }
+        function checkJSDocParameterTag(node) {
+            checkSourceElement(node.typeExpression);
+            if (!ts.getParameterSymbolFromJSDoc(node)) {
+                error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 143 /* QualifiedName */ ? node.name.right : node.name));
+            }
+        }
+        function checkJSDocAugmentsTag(node) {
+            var classLike = ts.getJSDocHost(node);
+            if (!ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
+                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
+                return;
+            }
+            var augmentsTags = ts.getAllJSDocTagsOfKind(classLike, 277 /* JSDocAugmentsTag */);
+            ts.Debug.assert(augmentsTags.length > 0);
+            if (augmentsTags.length > 1) {
+                error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
+            }
+            var name = getIdentifierFromEntityNameExpression(node.class.expression);
+            var extend = ts.getClassExtendsHeritageClauseElement(classLike);
+            if (extend) {
+                var className = getIdentifierFromEntityNameExpression(extend.expression);
+                if (className && name.escapedText !== className.escapedText) {
+                    error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className));
+                }
+            }
+        }
+        function getIdentifierFromEntityNameExpression(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return node;
+                case 179 /* PropertyAccessExpression */:
+                    return node.name;
+                default:
+                    return undefined;
+            }
+        }
+        function checkFunctionOrMethodDeclaration(node) {
+            checkDecorators(node);
+            checkSignatureDeclaration(node);
+            var functionFlags = ts.getFunctionFlags(node);
+            // Do not use hasDynamicName here, because that returns false for well known symbols.
+            // We want to perform checkComputedPropertyName for all computed properties, including
+            // well known symbols.
+            if (node.name && node.name.kind === 144 /* ComputedPropertyName */) {
+                // This check will account for methods in class/interface declarations,
+                // as well as accessors in classes/object literals
+                checkComputedPropertyName(node.name);
+            }
+            if (!ts.hasDynamicName(node)) {
+                // first we want to check the local symbol that contain this declaration
+                // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
+                // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
+                var symbol = getSymbolOfNode(node);
+                var localSymbol = node.localSymbol || symbol;
+                // Since the javascript won't do semantic analysis like typescript,
+                // if the javascript file comes before the typescript file and both contain same name functions,
+                // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
+                var firstDeclaration = ts.find(localSymbol.declarations, 
+                // Get first non javascript function declaration
+                function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 65536 /* JavaScriptFile */); });
+                // Only type check the symbol once
+                if (node === firstDeclaration) {
+                    checkFunctionOrConstructorSymbol(localSymbol);
+                }
+                if (symbol.parent) {
+                    // run check once for the first declaration
+                    if (ts.getDeclarationOfKind(symbol, node.kind) === node) {
+                        // run check on export symbol to check that modifiers agree across all exported declarations
+                        checkFunctionOrConstructorSymbol(symbol);
+                    }
+                }
+            }
+            checkSourceElement(node.body);
+            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
+            if ((functionFlags & 1 /* Generator */) === 0) {
+                var returnOrPromisedType = returnTypeNode && (functionFlags & 2 /* Async */
+                    ? checkAsyncFunctionReturnType(node) // Async function
+                    : getTypeFromTypeNode(returnTypeNode)); // normal function
+                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
+            }
+            if (produceDiagnostics && !returnTypeNode) {
+                // Report an implicit any error if there is no body, no explicit return type, and node is not a private method
+                // in an ambient context
+                if (noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
+                    reportImplicitAnyError(node, anyType);
+                }
+                if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(node.body)) {
+                    // A generator with a body and no type annotation can still cause errors. It can error if the
+                    // yielded values have no common supertype, or it can give an implicit any error if it has no
+                    // yielded values. The only way to trigger these errors is to try checking its return type.
+                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
+                }
+            }
+            registerForUnusedIdentifiersCheck(node);
+        }
+        function registerForUnusedIdentifiersCheck(node) {
+            if (deferredUnusedIdentifierNodes) {
+                deferredUnusedIdentifierNodes.push(node);
+            }
+        }
+        function checkUnusedIdentifiers() {
+            if (deferredUnusedIdentifierNodes) {
+                for (var _i = 0, deferredUnusedIdentifierNodes_1 = deferredUnusedIdentifierNodes; _i < deferredUnusedIdentifierNodes_1.length; _i++) {
+                    var node = deferredUnusedIdentifierNodes_1[_i];
+                    switch (node.kind) {
+                        case 265 /* SourceFile */:
+                        case 233 /* ModuleDeclaration */:
+                            checkUnusedModuleMembers(node);
+                            break;
+                        case 229 /* ClassDeclaration */:
+                        case 199 /* ClassExpression */:
+                            checkUnusedClassMembers(node);
+                            checkUnusedTypeParameters(node);
+                            break;
+                        case 230 /* InterfaceDeclaration */:
+                            checkUnusedTypeParameters(node);
+                            break;
+                        case 207 /* Block */:
+                        case 235 /* CaseBlock */:
+                        case 214 /* ForStatement */:
+                        case 215 /* ForInStatement */:
+                        case 216 /* ForOfStatement */:
+                            checkUnusedLocalsAndParameters(node);
+                            break;
+                        case 152 /* Constructor */:
+                        case 186 /* FunctionExpression */:
+                        case 228 /* FunctionDeclaration */:
+                        case 187 /* ArrowFunction */:
+                        case 151 /* MethodDeclaration */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                            if (node.body) {
+                                checkUnusedLocalsAndParameters(node);
+                            }
+                            checkUnusedTypeParameters(node);
+                            break;
+                        case 150 /* MethodSignature */:
+                        case 155 /* CallSignature */:
+                        case 156 /* ConstructSignature */:
+                        case 157 /* IndexSignature */:
+                        case 160 /* FunctionType */:
+                        case 161 /* ConstructorType */:
+                            checkUnusedTypeParameters(node);
+                            break;
+                        case 231 /* TypeAliasDeclaration */:
+                            checkUnusedTypeParameters(node);
+                            break;
+                    }
+                }
+            }
+        }
+        function checkUnusedLocalsAndParameters(node) {
+            if (node.parent.kind !== 230 /* InterfaceDeclaration */ && noUnusedIdentifiers && !ts.isInAmbientContext(node)) {
+                node.locals.forEach(function (local) {
+                    if (!local.isReferenced) {
+                        if (local.valueDeclaration && ts.getRootDeclaration(local.valueDeclaration).kind === 146 /* Parameter */) {
+                            var parameter = ts.getRootDeclaration(local.valueDeclaration);
+                            var name = ts.getNameOfDeclaration(local.valueDeclaration);
+                            if (compilerOptions.noUnusedParameters &&
+                                !ts.isParameterPropertyDeclaration(parameter) &&
+                                !ts.parameterIsThisKeyword(parameter) &&
+                                !parameterNameStartsWithUnderscore(name)) {
+                                error(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local));
+                            }
+                        }
+                        else if (compilerOptions.noUnusedLocals) {
+                            ts.forEach(local.declarations, function (d) { return errorUnusedLocal(d, ts.symbolName(local)); });
+                        }
+                    }
+                });
+            }
+        }
+        function isRemovedPropertyFromObjectSpread(node) {
+            if (ts.isBindingElement(node) && ts.isObjectBindingPattern(node.parent)) {
+                var lastElement = ts.lastOrUndefined(node.parent.elements);
+                return lastElement !== node && !!lastElement.dotDotDotToken;
+            }
+            return false;
+        }
+        function errorUnusedLocal(declaration, name) {
+            var node = ts.getNameOfDeclaration(declaration) || declaration;
+            if (isIdentifierThatStartsWithUnderScore(node)) {
+                var declaration_2 = ts.getRootDeclaration(node.parent);
+                if ((declaration_2.kind === 226 /* VariableDeclaration */ && ts.isForInOrOfStatement(declaration_2.parent.parent)) ||
+                    declaration_2.kind === 145 /* TypeParameter */) {
+                    return;
+                }
+            }
+            if (!isRemovedPropertyFromObjectSpread(node.kind === 71 /* Identifier */ ? node.parent : node)) {
+                error(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name);
+            }
+        }
+        function parameterNameStartsWithUnderscore(parameterName) {
+            return parameterName && isIdentifierThatStartsWithUnderScore(parameterName);
+        }
+        function isIdentifierThatStartsWithUnderScore(node) {
+            return node.kind === 71 /* Identifier */ && ts.idText(node).charCodeAt(0) === 95 /* _ */;
+        }
+        function checkUnusedClassMembers(node) {
+            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
+                if (node.members) {
+                    for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                        var member = _a[_i];
+                        if (member.kind === 151 /* MethodDeclaration */ || member.kind === 149 /* PropertyDeclaration */) {
+                            if (!member.symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) {
+                                error(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(member.symbol));
+                            }
+                        }
+                        else if (member.kind === 152 /* Constructor */) {
+                            for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
+                                var parameter = _c[_b];
+                                if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) {
+                                    error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        function checkUnusedTypeParameters(node) {
+            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
+                if (node.typeParameters) {
+                    // Only report errors on the last declaration for the type parameter container;
+                    // this ensures that all uses have been accounted for.
+                    var symbol = getSymbolOfNode(node);
+                    var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations);
+                    if (lastDeclaration !== node) {
+                        return;
+                    }
+                    for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
+                        var typeParameter = _a[_i];
+                        if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) {
+                            error(typeParameter.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(typeParameter.symbol));
+                        }
+                    }
+                }
+            }
+        }
+        function checkUnusedModuleMembers(node) {
+            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
+                node.locals.forEach(function (local) {
+                    if (!local.isReferenced && !local.exportSymbol) {
+                        for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
+                            var declaration = _a[_i];
+                            if (!ts.isAmbientModule(declaration)) {
+                                errorUnusedLocal(declaration, ts.symbolName(local));
+                            }
+                        }
+                    }
+                });
+            }
+        }
+        function checkBlock(node) {
+            // Grammar checking for SyntaxKind.Block
+            if (node.kind === 207 /* Block */) {
+                checkGrammarStatementInAmbientContext(node);
+            }
+            if (ts.isFunctionOrModuleBlock(node)) {
+                var saveFlowAnalysisDisabled = flowAnalysisDisabled;
+                ts.forEach(node.statements, checkSourceElement);
+                flowAnalysisDisabled = saveFlowAnalysisDisabled;
+            }
+            else {
+                ts.forEach(node.statements, checkSourceElement);
+            }
+            if (node.locals) {
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkCollisionWithArgumentsInGeneratedCode(node) {
+            // no rest parameters \ declaration context \ overload - no codegen impact
+            if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) {
+                return;
+            }
+            ts.forEach(node.parameters, function (p) {
+                if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) {
+                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
+                }
+            });
+        }
+        function needCollisionCheckForIdentifier(node, identifier, name) {
+            if (!(identifier && identifier.escapedText === name)) {
+                return false;
+            }
+            if (node.kind === 149 /* PropertyDeclaration */ ||
+                node.kind === 148 /* PropertySignature */ ||
+                node.kind === 151 /* MethodDeclaration */ ||
+                node.kind === 150 /* MethodSignature */ ||
+                node.kind === 153 /* GetAccessor */ ||
+                node.kind === 154 /* SetAccessor */) {
+                // it is ok to have member named '_super' or '_this' - member access is always qualified
+                return false;
+            }
+            if (ts.isInAmbientContext(node)) {
+                // ambient context - no codegen impact
+                return false;
+            }
+            var root = ts.getRootDeclaration(node);
+            if (root.kind === 146 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) {
+                // just an overload - no codegen impact
+                return false;
+            }
+            return true;
+        }
+        function checkCollisionWithCapturedThisVariable(node, name) {
+            if (needCollisionCheckForIdentifier(node, name, "_this")) {
+                potentialThisCollisions.push(node);
+            }
+        }
+        function checkCollisionWithCapturedNewTargetVariable(node, name) {
+            if (needCollisionCheckForIdentifier(node, name, "_newTarget")) {
+                potentialNewTargetCollisions.push(node);
+            }
+        }
+        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
+        function checkIfThisIsCapturedInEnclosingScope(node) {
+            ts.findAncestor(node, function (current) {
+                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
+                    var isDeclaration_1 = node.kind !== 71 /* Identifier */;
+                    if (isDeclaration_1) {
+                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
+                    }
+                    else {
+                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
+                    }
+                    return true;
+                }
+            });
+        }
+        function checkIfNewTargetIsCapturedInEnclosingScope(node) {
+            ts.findAncestor(node, function (current) {
+                if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) {
+                    var isDeclaration_2 = node.kind !== 71 /* Identifier */;
+                    if (isDeclaration_2) {
+                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
+                    }
+                    else {
+                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
+                    }
+                    return true;
+                }
+            });
+        }
+        function checkCollisionWithCapturedSuperVariable(node, name) {
+            if (!needCollisionCheckForIdentifier(node, name, "_super")) {
+                return;
+            }
+            // bubble up and find containing type
+            var enclosingClass = ts.getContainingClass(node);
+            // if containing type was not found or it is ambient - exit (no codegen)
+            if (!enclosingClass || ts.isInAmbientContext(enclosingClass)) {
+                return;
+            }
+            if (ts.getClassExtendsHeritageClauseElement(enclosingClass)) {
+                var isDeclaration_3 = node.kind !== 71 /* Identifier */;
+                if (isDeclaration_3) {
+                    error(node, ts.Diagnostics.Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference);
+                }
+                else {
+                    error(node, ts.Diagnostics.Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference);
+                }
+            }
+        }
+        function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
+            // No need to check for require or exports for ES6 modules and later
+            if (modulekind >= ts.ModuleKind.ES2015) {
+                return;
+            }
+            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
+                return;
+            }
+            // Uninstantiated modules shouldnt do this check
+            if (node.kind === 233 /* ModuleDeclaration */ && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
+                return;
+            }
+            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
+            var parent = getDeclarationContainer(node);
+            if (parent.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
+                // If the declaration happens to be in external module, report error that require and exports are reserved keywords
+                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
+            }
+        }
+        function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) {
+            if (languageVersion >= 4 /* ES2017 */ || !needCollisionCheckForIdentifier(node, name, "Promise")) {
+                return;
+            }
+            // Uninstantiated modules shouldnt do this check
+            if (node.kind === 233 /* ModuleDeclaration */ && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
+                return;
+            }
+            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
+            var parent = getDeclarationContainer(node);
+            if (parent.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 1024 /* HasAsyncFunctions */) {
+                // If the declaration happens to be in external module, report error that Promise is a reserved identifier.
+                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name));
+            }
+        }
+        function checkVarDeclaredNamesNotShadowed(node) {
+            // - ScriptBody : StatementList
+            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
+            // also occurs in the VarDeclaredNames of StatementList.
+            // - Block : { StatementList }
+            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
+            // also occurs in the VarDeclaredNames of StatementList.
+            // Variable declarations are hoisted to the top of their function scope. They can shadow
+            // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition
+            // by the binder as the declaration scope is different.
+            // A non-initialized declaration is a no-op as the block declaration will resolve before the var
+            // declaration. the problem is if the declaration has an initializer. this will act as a write to the
+            // block declared value. this is fine for let, but not const.
+            // Only consider declarations with initializers, uninitialized const declarations will not
+            // step on a let/const variable.
+            // Do not consider const and const declarations, as duplicate block-scoped declarations
+            // are handled by the binder.
+            // We are only looking for const declarations that step on let\const declarations from a
+            // different scope. e.g.:
+            //      {
+            //          const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
+            //          const x = 0; // symbol for this declaration will be 'symbol'
+            //      }
+            // skip block-scoped variables and parameters
+            if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
+                return;
+            }
+            // skip variable declarations that don't have initializers
+            // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
+            // so we'll always treat binding elements as initialized
+            if (node.kind === 226 /* VariableDeclaration */ && !node.initializer) {
+                return;
+            }
+            var symbol = getSymbolOfNode(node);
+            if (symbol.flags & 1 /* FunctionScopedVariable */) {
+                if (!ts.isIdentifier(node.name))
+                    throw ts.Debug.fail();
+                var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
+                if (localDeclarationSymbol &&
+                    localDeclarationSymbol !== symbol &&
+                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
+                    if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) {
+                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 227 /* VariableDeclarationList */);
+                        var container = varDeclList.parent.kind === 208 /* VariableStatement */ && varDeclList.parent.parent
+                            ? varDeclList.parent.parent
+                            : undefined;
+                        // names of block-scoped and function scoped variables can collide only
+                        // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
+                        var namesShareScope = container &&
+                            (container.kind === 207 /* Block */ && ts.isFunctionLike(container.parent) ||
+                                container.kind === 234 /* ModuleBlock */ ||
+                                container.kind === 233 /* ModuleDeclaration */ ||
+                                container.kind === 265 /* SourceFile */);
+                        // here we know that function scoped variable is shadowed by block scoped one
+                        // if they are defined in the same scope - binder has already reported redeclaration error
+                        // otherwise if variable has an initializer - show error that initialization will fail
+                        // since LHS will be block scoped name instead of function scoped
+                        if (!namesShareScope) {
+                            var name = symbolToString(localDeclarationSymbol);
+                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
+                        }
+                    }
+                }
+            }
+        }
+        // Check that a parameter initializer contains no references to parameters declared to the right of itself
+        function checkParameterInitializer(node) {
+            if (ts.getRootDeclaration(node).kind !== 146 /* Parameter */) {
+                return;
+            }
+            var func = ts.getContainingFunction(node);
+            visit(node.initializer);
+            function visit(n) {
+                if (ts.isTypeNode(n) || ts.isDeclarationName(n)) {
+                    // do not dive in types
+                    // skip declaration names (i.e. in object literal expressions)
+                    return;
+                }
+                if (n.kind === 179 /* PropertyAccessExpression */) {
+                    // skip property names in property access expression
+                    return visit(n.expression);
+                }
+                else if (n.kind === 71 /* Identifier */) {
+                    // check FunctionLikeDeclaration.locals (stores parameters\function local variable)
+                    // if it contains entry with a specified name
+                    var symbol = resolveName(n, n.escapedText, 107455 /* Value */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
+                    if (!symbol || symbol === unknownSymbol || !symbol.valueDeclaration) {
+                        return;
+                    }
+                    if (symbol.valueDeclaration === node) {
+                        error(n, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(node.name));
+                        return;
+                    }
+                    // locals map for function contain both parameters and function locals
+                    // so we need to do a bit of extra work to check if reference is legal
+                    var enclosingContainer = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
+                    if (enclosingContainer === func) {
+                        if (symbol.valueDeclaration.kind === 146 /* Parameter */ ||
+                            symbol.valueDeclaration.kind === 176 /* BindingElement */) {
+                            // it is ok to reference parameter in initializer if either
+                            // - parameter is located strictly on the left of current parameter declaration
+                            if (symbol.valueDeclaration.pos < node.pos) {
+                                return;
+                            }
+                            // - parameter is wrapped in function-like entity
+                            if (ts.findAncestor(n, function (current) {
+                                if (current === node.initializer) {
+                                    return "quit";
+                                }
+                                return ts.isFunctionLike(current.parent) ||
+                                    // computed property names/initializers in instance property declaration of class like entities
+                                    // are executed in constructor and thus deferred
+                                    (current.parent.kind === 149 /* PropertyDeclaration */ &&
+                                        !(ts.hasModifier(current.parent, 32 /* Static */)) &&
+                                        ts.isClassLike(current.parent.parent));
+                            })) {
+                                return;
+                            }
+                            // fall through to report error
+                        }
+                        error(n, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(node.name), ts.declarationNameToString(n));
+                    }
+                }
+                else {
+                    return ts.forEachChild(n, visit);
+                }
+            }
+        }
+        function convertAutoToAny(type) {
+            return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
+        }
+        // Check variable, parameter, or property declaration
+        function checkVariableLikeDeclaration(node) {
+            checkDecorators(node);
+            checkSourceElement(node.type);
+            // JSDoc `function(string, string): string` syntax results in parameters with no name
+            if (!node.name) {
+                return;
+            }
+            // For a computed property, just check the initializer and exit
+            // Do not use hasDynamicName here, because that returns false for well known symbols.
+            // We want to perform checkComputedPropertyName for all computed properties, including
+            // well known symbols.
+            if (node.name.kind === 144 /* ComputedPropertyName */) {
+                checkComputedPropertyName(node.name);
+                if (node.initializer) {
+                    checkExpressionCached(node.initializer);
+                }
+            }
+            if (node.kind === 176 /* BindingElement */) {
+                if (node.parent.kind === 174 /* ObjectBindingPattern */ && languageVersion < 5 /* ESNext */) {
+                    checkExternalEmitHelpers(node, 4 /* Rest */);
+                }
+                // check computed properties inside property names of binding elements
+                if (node.propertyName && node.propertyName.kind === 144 /* ComputedPropertyName */) {
+                    checkComputedPropertyName(node.propertyName);
+                }
+                // check private/protected variable access
+                var parent = node.parent.parent;
+                var parentType = getTypeForBindingElementParent(parent);
+                var name = node.propertyName || node.name;
+                var property = getPropertyOfType(parentType, ts.getTextOfPropertyName(name));
+                markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
+                if (parent.initializer && property) {
+                    checkPropertyAccessibility(parent, parent.initializer, parentType, property);
+                }
+            }
+            // For a binding pattern, check contained binding elements
+            if (ts.isBindingPattern(node.name)) {
+                if (node.name.kind === 175 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
+                    checkExternalEmitHelpers(node, 512 /* Read */);
+                }
+                ts.forEach(node.name.elements, checkSourceElement);
+            }
+            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
+            if (node.initializer && ts.getRootDeclaration(node).kind === 146 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
+                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
+                return;
+            }
+            // For a binding pattern, validate the initializer and exit
+            if (ts.isBindingPattern(node.name)) {
+                // Don't validate for-in initializer as it is already an error
+                if (node.initializer && node.parent.parent.kind !== 215 /* ForInStatement */) {
+                    checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
+                    checkParameterInitializer(node);
+                }
+                return;
+            }
+            var symbol = getSymbolOfNode(node);
+            var type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol));
+            if (node === symbol.valueDeclaration) {
+                // Node is the primary declaration of the symbol, just validate the initializer
+                // Don't validate for-in initializer as it is already an error
+                if (node.initializer && node.parent.parent.kind !== 215 /* ForInStatement */) {
+                    checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined);
+                    checkParameterInitializer(node);
+                }
+            }
+            else {
+                // Node is a secondary declaration, check that type is identical to primary declaration and check that
+                // initializer is consistent with type associated with the node
+                var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
+                if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
+                    error(node.name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
+                }
+                if (node.initializer) {
+                    checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined);
+                }
+                if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
+                    error(ts.getNameOfDeclaration(symbol.valueDeclaration), ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
+                    error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
+                }
+            }
+            if (node.kind !== 149 /* PropertyDeclaration */ && node.kind !== 148 /* PropertySignature */) {
+                // We know we don't have a binding pattern or computed name here
+                checkExportsOnMergedDeclarations(node);
+                if (node.kind === 226 /* VariableDeclaration */ || node.kind === 176 /* BindingElement */) {
+                    checkVarDeclaredNamesNotShadowed(node);
+                }
+                checkCollisionWithCapturedSuperVariable(node, node.name);
+                checkCollisionWithCapturedThisVariable(node, node.name);
+                checkCollisionWithCapturedNewTargetVariable(node, node.name);
+                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+            }
+        }
+        function areDeclarationFlagsIdentical(left, right) {
+            if ((left.kind === 146 /* Parameter */ && right.kind === 226 /* VariableDeclaration */) ||
+                (left.kind === 226 /* VariableDeclaration */ && right.kind === 146 /* Parameter */)) {
+                // Differences in optionality between parameters and variables are allowed.
+                return true;
+            }
+            if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) {
+                return false;
+            }
+            var interestingFlags = 8 /* Private */ |
+                16 /* Protected */ |
+                256 /* Async */ |
+                128 /* Abstract */ |
+                64 /* Readonly */ |
+                32 /* Static */;
+            return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags);
+        }
+        function checkVariableDeclaration(node) {
+            checkGrammarVariableDeclaration(node);
+            return checkVariableLikeDeclaration(node);
+        }
+        function checkBindingElement(node) {
+            checkGrammarBindingElement(node);
+            return checkVariableLikeDeclaration(node);
+        }
+        function checkVariableStatement(node) {
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
+            ts.forEach(node.declarationList.declarations, checkSourceElement);
+        }
+        function checkGrammarDisallowedModifiersOnObjectLiteralExpressionMethod(node) {
+            // We only disallow modifier on a method declaration if it is a property of object-literal-expression
+            if (node.modifiers && node.parent.kind === 178 /* ObjectLiteralExpression */) {
+                if (ts.getFunctionFlags(node) & 2 /* Async */) {
+                    if (node.modifiers.length > 1) {
+                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
+                    }
+                }
+                else {
+                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
+                }
+            }
+        }
+        function checkExpressionStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            checkExpression(node.expression);
+        }
+        function checkIfStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            checkExpression(node.expression);
+            checkSourceElement(node.thenStatement);
+            if (node.thenStatement.kind === 209 /* EmptyStatement */) {
+                error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement);
+            }
+            checkSourceElement(node.elseStatement);
+        }
+        function checkDoStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            checkSourceElement(node.statement);
+            checkExpression(node.expression);
+        }
+        function checkWhileStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            checkExpression(node.expression);
+            checkSourceElement(node.statement);
+        }
+        function checkForStatement(node) {
+            // Grammar checking
+            if (!checkGrammarStatementInAmbientContext(node)) {
+                if (node.initializer && node.initializer.kind === 227 /* VariableDeclarationList */) {
+                    checkGrammarVariableDeclarationList(node.initializer);
+                }
+            }
+            if (node.initializer) {
+                if (node.initializer.kind === 227 /* VariableDeclarationList */) {
+                    ts.forEach(node.initializer.declarations, checkVariableDeclaration);
+                }
+                else {
+                    checkExpression(node.initializer);
+                }
+            }
+            if (node.condition)
+                checkExpression(node.condition);
+            if (node.incrementor)
+                checkExpression(node.incrementor);
+            checkSourceElement(node.statement);
+            if (node.locals) {
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkForOfStatement(node) {
+            checkGrammarForInOrForOfStatement(node);
+            if (node.kind === 216 /* ForOfStatement */) {
+                if (node.awaitModifier) {
+                    var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node));
+                    if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 5 /* ESNext */) {
+                        // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
+                        checkExternalEmitHelpers(node, 16384 /* ForAwaitOfIncludes */);
+                    }
+                }
+                else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) {
+                    // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
+                    checkExternalEmitHelpers(node, 256 /* ForOfIncludes */);
+                }
+            }
+            // Check the LHS and RHS
+            // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
+            // via checkRightHandSideOfForOf.
+            // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference.
+            // Then check that the RHS is assignable to it.
+            if (node.initializer.kind === 227 /* VariableDeclarationList */) {
+                checkForInOrForOfVariableDeclaration(node);
+            }
+            else {
+                var varExpr = node.initializer;
+                var iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier);
+                // There may be a destructuring assignment on the left side
+                if (varExpr.kind === 177 /* ArrayLiteralExpression */ || varExpr.kind === 178 /* ObjectLiteralExpression */) {
+                    // iteratedType may be undefined. In this case, we still want to check the structure of
+                    // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like
+                    // to short circuit the type relation checking as much as possible, so we pass the unknownType.
+                    checkDestructuringAssignment(varExpr, iteratedType || unknownType);
+                }
+                else {
+                    var leftType = checkExpression(varExpr);
+                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access);
+                    // iteratedType will be undefined if the rightType was missing properties/signatures
+                    // required to get its iteratedType (like [Symbol.iterator] or next). This may be
+                    // because we accessed properties from anyType, or it may have led to an error inside
+                    // getElementTypeOfIterable.
+                    if (iteratedType) {
+                        checkTypeAssignableTo(iteratedType, leftType, varExpr, /*headMessage*/ undefined);
+                    }
+                }
+            }
+            checkSourceElement(node.statement);
+            if (node.locals) {
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkForInStatement(node) {
+            // Grammar checking
+            checkGrammarForInOrForOfStatement(node);
+            var rightType = checkNonNullExpression(node.expression);
+            // TypeScript 1.0 spec  (April 2014): 5.4
+            // In a 'for-in' statement of the form
+            // for (let VarDecl in Expr) Statement
+            //   VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
+            //   and Expr must be an expression of type Any, an object type, or a type parameter type.
+            if (node.initializer.kind === 227 /* VariableDeclarationList */) {
+                var variable = node.initializer.declarations[0];
+                if (variable && ts.isBindingPattern(variable.name)) {
+                    error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
+                }
+                checkForInOrForOfVariableDeclaration(node);
+            }
+            else {
+                // In a 'for-in' statement of the form
+                // for (Var in Expr) Statement
+                //   Var must be an expression classified as a reference of type Any or the String primitive type,
+                //   and Expr must be an expression of type Any, an object type, or a type parameter type.
+                var varExpr = node.initializer;
+                var leftType = checkExpression(varExpr);
+                if (varExpr.kind === 177 /* ArrayLiteralExpression */ || varExpr.kind === 178 /* ObjectLiteralExpression */) {
+                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
+                }
+                else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
+                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
+                }
+                else {
+                    // run check only former check succeeded to avoid cascading errors
+                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access);
+                }
+            }
+            // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
+            // in this case error about missing name is already reported - do not report extra one
+            if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) {
+                error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
+            }
+            checkSourceElement(node.statement);
+            if (node.locals) {
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkForInOrForOfVariableDeclaration(iterationStatement) {
+            var variableDeclarationList = iterationStatement.initializer;
+            // checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
+            if (variableDeclarationList.declarations.length >= 1) {
+                var decl = variableDeclarationList.declarations[0];
+                checkVariableDeclaration(decl);
+            }
+        }
+        function checkRightHandSideOfForOf(rhsExpression, awaitModifier) {
+            var expressionType = checkNonNullExpression(rhsExpression);
+            return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true, awaitModifier !== undefined);
+        }
+        function checkIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables) {
+            if (isTypeAny(inputType)) {
+                return inputType;
+            }
+            return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, /*checkAssignability*/ true) || anyType;
+        }
+        /**
+         * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
+         * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
+         * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
+         */
+        function getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, checkAssignability) {
+            var uplevelIteration = languageVersion >= 2 /* ES2015 */;
+            var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
+            // Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
+            // or higher, when inside of an async generator or for-await-if, or when
+            // downlevelIteration is requested.
+            if (uplevelIteration || downlevelIteration || allowAsyncIterables) {
+                // We only report errors for an invalid iterable type in ES2015 or higher.
+                var iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
+                if (iteratedType || uplevelIteration) {
+                    return iteratedType;
+                }
+            }
+            var arrayType = inputType;
+            var reportedError = false;
+            var hasStringConstituent = false;
+            // If strings are permitted, remove any string-like constituents from the array type.
+            // This allows us to find other non-string element types from an array unioned with
+            // a string.
+            if (allowStringInput) {
+                if (arrayType.flags & 65536 /* Union */) {
+                    // After we remove all types that are StringLike, we will know if there was a string constituent
+                    // based on whether the result of filter is a new array.
+                    var arrayTypes = inputType.types;
+                    var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 262178 /* StringLike */); });
+                    if (filteredTypes !== arrayTypes) {
+                        arrayType = getUnionType(filteredTypes, /*subtypeReduction*/ true);
+                    }
+                }
+                else if (arrayType.flags & 262178 /* StringLike */) {
+                    arrayType = neverType;
+                }
+                hasStringConstituent = arrayType !== inputType;
+                if (hasStringConstituent) {
+                    if (languageVersion < 1 /* ES5 */) {
+                        if (errorNode) {
+                            error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher);
+                            reportedError = true;
+                        }
+                    }
+                    // Now that we've removed all the StringLike types, if no constituents remain, then the entire
+                    // arrayOrStringType was a string.
+                    if (arrayType.flags & 8192 /* Never */) {
+                        return stringType;
+                    }
+                }
+            }
+            if (!isArrayLikeType(arrayType)) {
+                if (errorNode && !reportedError) {
+                    // Which error we report depends on whether we allow strings or if there was a
+                    // string constituent. For example, if the input type is number | string, we
+                    // want to say that number is not an array type. But if the input was just
+                    // number and string input is allowed, we want to say that number is not an
+                    // array type or a string type.
+                    var diagnostic = !allowStringInput || hasStringConstituent
+                        ? downlevelIteration
+                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
+                            : ts.Diagnostics.Type_0_is_not_an_array_type
+                        : downlevelIteration
+                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
+                            : ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
+                    error(errorNode, diagnostic, typeToString(arrayType));
+                }
+                return hasStringConstituent ? stringType : undefined;
+            }
+            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */);
+            if (hasStringConstituent && arrayElementType) {
+                // This is just an optimization for the case where arrayOrStringType is string | string[]
+                if (arrayElementType.flags & 262178 /* StringLike */) {
+                    return stringType;
+                }
+                return getUnionType([arrayElementType, stringType], /*subtypeReduction*/ true);
+            }
+            return arrayElementType;
+        }
+        /**
+         * We want to treat type as an iterable, and get the type it is an iterable of. The iterable
+         * must have the following structure (annotated with the names of the variables below):
+         *
+         *     { // iterable
+         *         [Symbol.iterator]: { // iteratorMethod
+         *             (): Iterator<T>
+         *         }
+         *     }
+         *
+         * For an async iterable, we expect the following structure:
+         *
+         *     { // iterable
+         *         [Symbol.asyncIterator]: { // iteratorMethod
+         *             (): AsyncIterator<T>
+         *         }
+         *     }
+         *
+         * T is the type we are after. At every level that involves analyzing return types
+         * of signatures, we union the return types of all the signatures.
+         *
+         * Another thing to note is that at any step of this process, we could run into a dead end,
+         * meaning either the property is missing, or we run into the anyType. If either of these things
+         * happens, we return undefined to signal that we could not find the iterated type. If a property
+         * is missing, and the previous step did not result in 'any', then we also give an error if the
+         * caller requested it. Then the caller can decide what to do in the case where there is no iterated
+         * type. This is different from returning anyType, because that would signify that we have matched the
+         * whole pattern and that T (above) is 'any'.
+         *
+         * For a **for-of** statement, `yield*` (in a normal generator), spread, array
+         * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()`
+         * method.
+         *
+         * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method.
+         *
+         * For a **for-await-of** statement or a `yield*` in an async generator we will look for
+         * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
+         */
+        function getIteratedTypeOfIterable(type, errorNode, allowAsyncIterables, allowSyncIterables, checkAssignability) {
+            if (isTypeAny(type)) {
+                return undefined;
+            }
+            return mapType(type, getIteratedType);
+            function getIteratedType(type) {
+                var typeAsIterable = type;
+                if (allowAsyncIterables) {
+                    if (typeAsIterable.iteratedTypeOfAsyncIterable) {
+                        return typeAsIterable.iteratedTypeOfAsyncIterable;
+                    }
+                    // As an optimization, if the type is an instantiation of the global `AsyncIterable<T>`
+                    // or the global `AsyncIterableIterator<T>` then just grab its type argument.
+                    if (isReferenceToType(type, getGlobalAsyncIterableType(/*reportErrors*/ false)) ||
+                        isReferenceToType(type, getGlobalAsyncIterableIteratorType(/*reportErrors*/ false))) {
+                        return typeAsIterable.iteratedTypeOfAsyncIterable = type.typeArguments[0];
+                    }
+                }
+                if (allowSyncIterables) {
+                    if (typeAsIterable.iteratedTypeOfIterable) {
+                        return typeAsIterable.iteratedTypeOfIterable;
+                    }
+                    // As an optimization, if the type is an instantiation of the global `Iterable<T>` or
+                    // `IterableIterator<T>` then just grab its type argument.
+                    if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
+                        isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
+                        return typeAsIterable.iteratedTypeOfIterable = type.typeArguments[0];
+                    }
+                }
+                var asyncMethodType = allowAsyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("asyncIterator"));
+                var methodType = asyncMethodType || (allowSyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")));
+                if (isTypeAny(methodType)) {
+                    return undefined;
+                }
+                var signatures = methodType && getSignaturesOfType(methodType, 0 /* Call */);
+                if (!ts.some(signatures)) {
+                    if (errorNode) {
+                        error(errorNode, allowAsyncIterables
+                            ? ts.Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
+                            : ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
+                        // only report on the first error
+                        errorNode = undefined;
+                    }
+                    return undefined;
+                }
+                var returnType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
+                var iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType);
+                if (checkAssignability && errorNode && iteratedType) {
+                    // If `checkAssignability` was specified, we were called from
+                    // `checkIteratedTypeOrElementType`. As such, we need to validate that
+                    // the type passed in is actually an Iterable.
+                    checkTypeAssignableTo(type, asyncMethodType
+                        ? createAsyncIterableType(iteratedType)
+                        : createIterableType(iteratedType), errorNode);
+                }
+                return asyncMethodType
+                    ? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType
+                    : typeAsIterable.iteratedTypeOfIterable = iteratedType;
+            }
+        }
+        /**
+         * This function has very similar logic as getIteratedTypeOfIterable, except that it operates on
+         * Iterators instead of Iterables. Here is the structure:
+         *
+         *  { // iterator
+         *      next: { // nextMethod
+         *          (): { // nextResult
+         *              value: T // nextValue
+         *          }
+         *      }
+         *  }
+         *
+         * For an async iterator, we expect the following structure:
+         *
+         *  { // iterator
+         *      next: { // nextMethod
+         *          (): PromiseLike<{ // nextResult
+         *              value: T // nextValue
+         *          }>
+         *      }
+         *  }
+         */
+        function getIteratedTypeOfIterator(type, errorNode, isAsyncIterator) {
+            if (isTypeAny(type)) {
+                return undefined;
+            }
+            var typeAsIterator = type;
+            if (isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator) {
+                return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator;
+            }
+            // As an optimization, if the type is an instantiation of the global `Iterator<T>` (for
+            // a non-async iterator) or the global `AsyncIterator<T>` (for an async-iterator) then
+            // just grab its type argument.
+            var getIteratorType = isAsyncIterator ? getGlobalAsyncIteratorType : getGlobalIteratorType;
+            if (isReferenceToType(type, getIteratorType(/*reportErrors*/ false))) {
+                return isAsyncIterator
+                    ? typeAsIterator.iteratedTypeOfAsyncIterator = type.typeArguments[0]
+                    : typeAsIterator.iteratedTypeOfIterator = type.typeArguments[0];
+            }
+            // Both async and non-async iterators must have a `next` method.
+            var nextMethod = getTypeOfPropertyOfType(type, "next");
+            if (isTypeAny(nextMethod)) {
+                return undefined;
+            }
+            var nextMethodSignatures = nextMethod ? getSignaturesOfType(nextMethod, 0 /* Call */) : ts.emptyArray;
+            if (nextMethodSignatures.length === 0) {
+                if (errorNode) {
+                    error(errorNode, isAsyncIterator
+                        ? ts.Diagnostics.An_async_iterator_must_have_a_next_method
+                        : ts.Diagnostics.An_iterator_must_have_a_next_method);
+                }
+                return undefined;
+            }
+            var nextResult = getUnionType(ts.map(nextMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
+            if (isTypeAny(nextResult)) {
+                return undefined;
+            }
+            // For an async iterator, we must get the awaited type of the return type.
+            if (isAsyncIterator) {
+                nextResult = getAwaitedTypeOfPromise(nextResult, errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property);
+                if (isTypeAny(nextResult)) {
+                    return undefined;
+                }
+            }
+            var nextValue = nextResult && getTypeOfPropertyOfType(nextResult, "value");
+            if (!nextValue) {
+                if (errorNode) {
+                    error(errorNode, isAsyncIterator
+                        ? ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property
+                        : ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property);
+                }
+                return undefined;
+            }
+            return isAsyncIterator
+                ? typeAsIterator.iteratedTypeOfAsyncIterator = nextValue
+                : typeAsIterator.iteratedTypeOfIterator = nextValue;
+        }
+        /**
+         * A generator may have a return type of `Iterator<T>`, `Iterable<T>`, or
+         * `IterableIterator<T>`. An async generator may have a return type of `AsyncIterator<T>`,
+         * `AsyncIterable<T>`, or `AsyncIterableIterator<T>`. This function can be used to extract
+         * the iterated type from this return type for contextual typing and verifying signatures.
+         */
+        function getIteratedTypeOfGenerator(returnType, isAsyncGenerator) {
+            if (isTypeAny(returnType)) {
+                return undefined;
+            }
+            return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, /*allowAsyncIterables*/ isAsyncGenerator, /*allowSyncIterables*/ !isAsyncGenerator, /*checkAssignability*/ false)
+                || getIteratedTypeOfIterator(returnType, /*errorNode*/ undefined, isAsyncGenerator);
+        }
+        function checkBreakOrContinueStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
+            // TODO: Check that target label is valid
+        }
+        function isGetAccessorWithAnnotatedSetAccessor(node) {
+            return node.kind === 153 /* GetAccessor */
+                && ts.getEffectiveSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(node.symbol, 154 /* SetAccessor */)) !== undefined;
+        }
+        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
+            var unwrappedReturnType = (ts.getFunctionFlags(func) & 3 /* AsyncGenerator */) === 2 /* Async */
+                ? getPromisedTypeOfPromise(returnType) // Async function
+                : returnType; // AsyncGenerator function, Generator function, or normal function
+            return unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 1024 /* Void */ | 1 /* Any */);
+        }
+        function checkReturnStatement(node) {
+            // Grammar checking
+            if (!checkGrammarStatementInAmbientContext(node)) {
+                var functionBlock = ts.getContainingFunction(node);
+                if (!functionBlock) {
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
+                }
+            }
+            var func = ts.getContainingFunction(node);
+            if (func) {
+                var signature = getSignatureFromDeclaration(func);
+                var returnType = getReturnTypeOfSignature(signature);
+                if (strictNullChecks || node.expression || returnType.flags & 8192 /* Never */) {
+                    var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
+                    var functionFlags = ts.getFunctionFlags(func);
+                    if (functionFlags & 1 /* Generator */) {
+                        // A generator does not need its return expressions checked against its return type.
+                        // Instead, the yield expressions are checked against the element type.
+                        // TODO: Check return expressions of generators when return type tracking is added
+                        // for generators.
+                        return;
+                    }
+                    if (func.kind === 154 /* SetAccessor */) {
+                        if (node.expression) {
+                            error(node, ts.Diagnostics.Setters_cannot_return_a_value);
+                        }
+                    }
+                    else if (func.kind === 152 /* Constructor */) {
+                        if (node.expression && !checkTypeAssignableTo(exprType, returnType, node)) {
+                            error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
+                        }
+                    }
+                    else if (ts.getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) {
+                        if (functionFlags & 2 /* Async */) {
+                            var promisedType = getPromisedTypeOfPromise(returnType);
+                            var awaitedType = checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
+                            if (promisedType) {
+                                // If the function has a return type, but promisedType is
+                                // undefined, an error will be reported in checkAsyncFunctionReturnType
+                                // so we don't need to report one here.
+                                checkTypeAssignableTo(awaitedType, promisedType, node);
+                            }
+                        }
+                        else {
+                            checkTypeAssignableTo(exprType, returnType, node);
+                        }
+                    }
+                }
+                else if (func.kind !== 152 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
+                    // The function has a return type, but the return statement doesn't have an expression.
+                    error(node, ts.Diagnostics.Not_all_code_paths_return_a_value);
+                }
+            }
+        }
+        function checkWithStatement(node) {
+            // Grammar checking for withStatement
+            if (!checkGrammarStatementInAmbientContext(node)) {
+                if (node.flags & 16384 /* AwaitContext */) {
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
+                }
+            }
+            checkExpression(node.expression);
+            var sourceFile = ts.getSourceFileOfNode(node);
+            if (!hasParseDiagnostics(sourceFile)) {
+                var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start;
+                var end = node.statement.pos;
+                grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any);
+            }
+        }
+        function checkSwitchStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            var firstDefaultClause;
+            var hasDuplicateDefaultClause = false;
+            var expressionType = checkExpression(node.expression);
+            var expressionIsLiteral = isLiteralType(expressionType);
+            ts.forEach(node.caseBlock.clauses, function (clause) {
+                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
+                if (clause.kind === 258 /* DefaultClause */ && !hasDuplicateDefaultClause) {
+                    if (firstDefaultClause === undefined) {
+                        firstDefaultClause = clause;
+                    }
+                    else {
+                        var sourceFile = ts.getSourceFileOfNode(node);
+                        var start = ts.skipTrivia(sourceFile.text, clause.pos);
+                        var end = clause.statements.length > 0 ? clause.statements[0].pos : clause.end;
+                        grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
+                        hasDuplicateDefaultClause = true;
+                    }
+                }
+                if (produceDiagnostics && clause.kind === 257 /* CaseClause */) {
+                    var caseClause = clause;
+                    // TypeScript 1.0 spec (April 2014): 5.9
+                    // In a 'switch' statement, each 'case' expression must be of a type that is comparable
+                    // to or from the type of the 'switch' expression.
+                    var caseType = checkExpression(caseClause.expression);
+                    var caseIsLiteral = isLiteralType(caseType);
+                    var comparedExpressionType = expressionType;
+                    if (!caseIsLiteral || !expressionIsLiteral) {
+                        caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
+                        comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
+                    }
+                    if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
+                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
+                        checkTypeComparableTo(caseType, comparedExpressionType, caseClause.expression, /*headMessage*/ undefined);
+                    }
+                }
+                ts.forEach(clause.statements, checkSourceElement);
+            });
+            if (node.caseBlock.locals) {
+                registerForUnusedIdentifiersCheck(node.caseBlock);
+            }
+        }
+        function checkLabeledStatement(node) {
+            // Grammar checking
+            if (!checkGrammarStatementInAmbientContext(node)) {
+                ts.findAncestor(node.parent, function (current) {
+                    if (ts.isFunctionLike(current)) {
+                        return "quit";
+                    }
+                    if (current.kind === 222 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) {
+                        var sourceFile = ts.getSourceFileOfNode(node);
+                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNodeFromSourceText(sourceFile.text, node.label));
+                        return true;
+                    }
+                });
+            }
+            // ensure that label is unique
+            checkSourceElement(node.statement);
+        }
+        function checkThrowStatement(node) {
+            // Grammar checking
+            if (!checkGrammarStatementInAmbientContext(node)) {
+                if (node.expression === undefined) {
+                    grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here);
+                }
+            }
+            if (node.expression) {
+                checkExpression(node.expression);
+            }
+        }
+        function checkTryStatement(node) {
+            // Grammar checking
+            checkGrammarStatementInAmbientContext(node);
+            checkBlock(node.tryBlock);
+            var catchClause = node.catchClause;
+            if (catchClause) {
+                // Grammar checking
+                if (catchClause.variableDeclaration) {
+                    if (catchClause.variableDeclaration.type) {
+                        grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation);
+                    }
+                    else if (catchClause.variableDeclaration.initializer) {
+                        grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
+                    }
+                    else {
+                        var blockLocals_1 = catchClause.block.locals;
+                        if (blockLocals_1) {
+                            ts.forEachKey(catchClause.locals, function (caughtName) {
+                                var blockLocal = blockLocals_1.get(caughtName);
+                                if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) {
+                                    grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
+                                }
+                            });
+                        }
+                    }
+                }
+                checkBlock(catchClause.block);
+            }
+            if (node.finallyBlock) {
+                checkBlock(node.finallyBlock);
+            }
+        }
+        function checkIndexConstraints(type) {
+            var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
+            var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
+            var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
+            var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
+            if (stringIndexType || numberIndexType) {
+                ts.forEach(getPropertiesOfObjectType(type), function (prop) {
+                    var propType = getTypeOfSymbol(prop);
+                    checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
+                    checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
+                });
+                if (getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(type.symbol.valueDeclaration)) {
+                    var classDeclaration = type.symbol.valueDeclaration;
+                    for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) {
+                        var member = _a[_i];
+                        // Only process instance properties with computed names here.
+                        // Static properties cannot be in conflict with indexers,
+                        // and properties with literal names were already checked.
+                        if (!ts.hasModifier(member, 32 /* Static */) && ts.hasDynamicName(member)) {
+                            var propType = getTypeOfSymbol(member.symbol);
+                            checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
+                            checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
+                        }
+                    }
+                }
+            }
+            var errorNode;
+            if (stringIndexType && numberIndexType) {
+                errorNode = declaredNumberIndexer || declaredStringIndexer;
+                // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer
+                if (!errorNode && (getObjectFlags(type) & 2 /* Interface */)) {
+                    var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
+                    errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
+                }
+            }
+            if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) {
+                error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
+            }
+            function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) {
+                if (!indexType) {
+                    return;
+                }
+                var propDeclaration = prop.valueDeclaration;
+                // index is numeric and property name is not valid numeric literal
+                if (indexKind === 1 /* Number */ && !(propDeclaration ? isNumericName(ts.getNameOfDeclaration(propDeclaration)) : isNumericLiteralName(prop.escapedName))) {
+                    return;
+                }
+                // perform property check if property or indexer is declared in 'type'
+                // this allows us to rule out cases when both property and indexer are inherited from the base class
+                var errorNode;
+                if (propDeclaration &&
+                    (propDeclaration.kind === 194 /* BinaryExpression */ ||
+                        ts.getNameOfDeclaration(propDeclaration).kind === 144 /* ComputedPropertyName */ ||
+                        prop.parent === containingType.symbol)) {
+                    errorNode = propDeclaration;
+                }
+                else if (indexDeclaration) {
+                    errorNode = indexDeclaration;
+                }
+                else if (getObjectFlags(containingType) & 2 /* Interface */) {
+                    // for interfaces property and indexer might be inherited from different bases
+                    // check if any base class already has both property and indexer.
+                    // check should be performed only if 'type' is the first type that brings property\indexer together
+                    var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); });
+                    errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0];
+                }
+                if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
+                    var errorMessage = indexKind === 0 /* String */
+                        ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2
+                        : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
+                    error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
+                }
+            }
+        }
+        function checkTypeNameIsReserved(name, message) {
+            // TS 1.0 spec (April 2014): 3.6.1
+            // The predefined type keywords are reserved and cannot be used as names of user defined types.
+            switch (name.escapedText) {
+                case "any":
+                case "number":
+                case "boolean":
+                case "string":
+                case "symbol":
+                case "void":
+                case "object":
+                    error(name, message, name.escapedText);
+            }
+        }
+        /**
+         * Check each type parameter and check that type parameters have no duplicate type parameter declarations
+         */
+        function checkTypeParameters(typeParameterDeclarations) {
+            if (typeParameterDeclarations) {
+                var seenDefault = false;
+                for (var i = 0; i < typeParameterDeclarations.length; i++) {
+                    var node = typeParameterDeclarations[i];
+                    checkTypeParameter(node);
+                    if (produceDiagnostics) {
+                        if (node.default) {
+                            seenDefault = true;
+                        }
+                        else if (seenDefault) {
+                            error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
+                        }
+                        for (var j = 0; j < i; j++) {
+                            if (typeParameterDeclarations[j].symbol === node.symbol) {
+                                error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        /** Check that type parameter lists are identical across multiple declarations */
+        function checkTypeParameterListsIdentical(symbol) {
+            if (symbol.declarations.length === 1) {
+                return;
+            }
+            var links = getSymbolLinks(symbol);
+            if (!links.typeParametersChecked) {
+                links.typeParametersChecked = true;
+                var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol);
+                if (declarations.length <= 1) {
+                    return;
+                }
+                var type = getDeclaredTypeOfSymbol(symbol);
+                if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) {
+                    // Report an error on every conflicting declaration.
+                    var name = symbolToString(symbol);
+                    for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) {
+                        var declaration = declarations_5[_i];
+                        error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name);
+                    }
+                }
+            }
+        }
+        function areTypeParametersIdentical(declarations, typeParameters) {
+            var maxTypeArgumentCount = ts.length(typeParameters);
+            var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
+            for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
+                var declaration = declarations_6[_i];
+                // If this declaration has too few or too many type parameters, we report an error
+                var numTypeParameters = ts.length(declaration.typeParameters);
+                if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) {
+                    return false;
+                }
+                for (var i = 0; i < numTypeParameters; i++) {
+                    var source = declaration.typeParameters[i];
+                    var target = typeParameters[i];
+                    // If the type parameter node does not have the same as the resolved type
+                    // parameter at this position, we report an error.
+                    if (source.name.escapedText !== target.symbol.escapedName) {
+                        return false;
+                    }
+                    // If the type parameter node does not have an identical constraint as the resolved
+                    // type parameter at this position, we report an error.
+                    var sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
+                    var targetConstraint = getConstraintFromTypeParameter(target);
+                    if ((sourceConstraint || targetConstraint) &&
+                        (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) {
+                        return false;
+                    }
+                    // If the type parameter node has a default and it is not identical to the default
+                    // for the type parameter at this position, we report an error.
+                    var sourceDefault = source.default && getTypeFromTypeNode(source.default);
+                    var targetDefault = getDefaultFromTypeParameter(target);
+                    if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        function checkClassExpression(node) {
+            checkClassLikeDeclaration(node);
+            checkNodeDeferred(node);
+            return getTypeOfSymbol(getSymbolOfNode(node));
+        }
+        function checkClassExpressionDeferred(node) {
+            ts.forEach(node.members, checkSourceElement);
+            registerForUnusedIdentifiersCheck(node);
+        }
+        function checkClassDeclaration(node) {
+            if (!node.name && !ts.hasModifier(node, 512 /* Default */)) {
+                grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
+            }
+            checkClassLikeDeclaration(node);
+            ts.forEach(node.members, checkSourceElement);
+            registerForUnusedIdentifiersCheck(node);
+        }
+        function checkClassLikeDeclaration(node) {
+            checkGrammarClassLikeDeclaration(node);
+            checkDecorators(node);
+            if (node.name) {
+                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
+                checkCollisionWithCapturedThisVariable(node, node.name);
+                checkCollisionWithCapturedNewTargetVariable(node, node.name);
+                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+            }
+            checkTypeParameters(node.typeParameters);
+            checkExportsOnMergedDeclarations(node);
+            var symbol = getSymbolOfNode(node);
+            var type = getDeclaredTypeOfSymbol(symbol);
+            var typeWithThis = getTypeWithThisArgument(type);
+            var staticType = getTypeOfSymbol(symbol);
+            checkTypeParameterListsIdentical(symbol);
+            checkClassForDuplicateDeclarations(node);
+            // Only check for reserved static identifiers on non-ambient context.
+            if (!ts.isInAmbientContext(node)) {
+                checkClassForStaticPropertyNameConflicts(node);
+            }
+            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
+            if (baseTypeNode) {
+                if (languageVersion < 2 /* ES2015 */) {
+                    checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */);
+                }
+                var baseTypes = getBaseTypes(type);
+                if (baseTypes.length && produceDiagnostics) {
+                    var baseType_1 = baseTypes[0];
+                    var baseConstructorType = getBaseConstructorTypeOfClass(type);
+                    var staticBaseType = getApparentType(baseConstructorType);
+                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
+                    checkSourceElement(baseTypeNode.expression);
+                    if (ts.some(baseTypeNode.typeArguments)) {
+                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
+                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) {
+                            var constructor = _a[_i];
+                            if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) {
+                                break;
+                            }
+                        }
+                    }
+                    checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType_1, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
+                    checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
+                    if (baseConstructorType.flags & 540672 /* TypeVariable */ && !isMixinConstructorType(staticType)) {
+                        error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
+                    }
+                    if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 540672 /* TypeVariable */)) {
+                        // When the static base type is a "class-like" constructor function (but not actually a class), we verify
+                        // that all instantiated base constructor signatures return the same type. We can simply compare the type
+                        // references (as opposed to checking the structure of the types) because elsewhere we have already checked
+                        // that the base type is a class or interface type (and not, for example, an anonymous object type).
+                        var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode);
+                        if (ts.forEach(constructors, function (sig) { return getReturnTypeOfSignature(sig) !== baseType_1; })) {
+                            error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type);
+                        }
+                    }
+                    checkKindsOfPropertyMemberOverrides(type, baseType_1);
+                }
+            }
+            var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node);
+            if (implementedTypeNodes) {
+                for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) {
+                    var typeRefNode = implementedTypeNodes_1[_b];
+                    if (!ts.isEntityNameExpression(typeRefNode.expression)) {
+                        error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
+                    }
+                    checkTypeReferenceNode(typeRefNode);
+                    if (produceDiagnostics) {
+                        var t = getTypeFromTypeNode(typeRefNode);
+                        if (t !== unknownType) {
+                            if (isValidBaseType(t)) {
+                                checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_implements_interface_1);
+                            }
+                            else {
+                                error(typeRefNode, ts.Diagnostics.A_class_may_only_implement_another_class_or_interface);
+                            }
+                        }
+                    }
+                }
+            }
+            if (produceDiagnostics) {
+                checkIndexConstraints(type);
+                checkTypeForDuplicateIndexSignatures(node);
+            }
+        }
+        function checkBaseTypeAccessibility(type, node) {
+            var signatures = getSignaturesOfType(type, 1 /* Construct */);
+            if (signatures.length) {
+                var declaration = signatures[0].declaration;
+                if (declaration && ts.hasModifier(declaration, 8 /* Private */)) {
+                    var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol);
+                    if (!isNodeWithinClass(node, typeClassDeclaration)) {
+                        error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
+                    }
+                }
+            }
+        }
+        function getTargetSymbol(s) {
+            // if symbol is instantiated its flags are not copied from the 'target'
+            // so we'll need to get back original 'target' symbol to work with correct set of flags
+            return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s;
+        }
+        function getClassLikeDeclarationOfSymbol(symbol) {
+            return ts.forEach(symbol.declarations, function (d) { return ts.isClassLike(d) ? d : undefined; });
+        }
+        function getClassOrInterfaceDeclarationsOfSymbol(symbol) {
+            return ts.filter(symbol.declarations, function (d) {
+                return d.kind === 229 /* ClassDeclaration */ || d.kind === 230 /* InterfaceDeclaration */;
+            });
+        }
+        function checkKindsOfPropertyMemberOverrides(type, baseType) {
+            // TypeScript 1.0 spec (April 2014): 8.2.3
+            // A derived class inherits all members from its base class it doesn't override.
+            // Inheritance means that a derived class implicitly contains all non - overridden members of the base class.
+            // Both public and private property members are inherited, but only public property members can be overridden.
+            // A property member in a derived class is said to override a property member in a base class
+            // when the derived class property member has the same name and kind(instance or static)
+            // as the base class property member.
+            // The type of an overriding property member must be assignable(section 3.8.4)
+            // to the type of the overridden property member, or otherwise a compile - time error occurs.
+            // Base class instance member functions can be overridden by derived class instance member functions,
+            // but not by other kinds of members.
+            // Base class instance member variables and accessors can be overridden by
+            // derived class instance member variables and accessors, but not by other kinds of members.
+            // NOTE: assignability is checked in checkClassDeclaration
+            var baseProperties = getPropertiesOfType(baseType);
+            for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) {
+                var baseProperty = baseProperties_1[_i];
+                var base = getTargetSymbol(baseProperty);
+                if (base.flags & 4194304 /* Prototype */) {
+                    continue;
+                }
+                var derived = getTargetSymbol(getPropertyOfObjectType(type, base.escapedName));
+                var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base);
+                ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
+                if (derived) {
+                    // In order to resolve whether the inherited method was overridden in the base class or not,
+                    // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
+                    // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
+                    if (derived === base) {
+                        // derived class inherits base without override/redeclaration
+                        var derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol);
+                        // It is an error to inherit an abstract member without implementing it or being declared abstract.
+                        // If there is no declaration for the derived class (as in the case of class expressions),
+                        // then the class cannot be declared abstract.
+                        if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) {
+                            if (derivedClassDecl.kind === 199 /* ClassExpression */) {
+                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType));
+                            }
+                            else {
+                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType));
+                            }
+                        }
+                    }
+                    else {
+                        // derived overrides base.
+                        var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived);
+                        if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) {
+                            // either base or derived property is private - not override, skip it
+                            continue;
+                        }
+                        if (isMethodLike(base) && isMethodLike(derived) || base.flags & 98308 /* PropertyOrAccessor */ && derived.flags & 98308 /* PropertyOrAccessor */) {
+                            // method is overridden with method or property/accessor is overridden with property/accessor - correct case
+                            continue;
+                        }
+                        var errorMessage = void 0;
+                        if (isMethodLike(base)) {
+                            if (derived.flags & 98304 /* Accessor */) {
+                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
+                            }
+                            else {
+                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
+                            }
+                        }
+                        else if (base.flags & 4 /* Property */) {
+                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
+                        }
+                        else {
+                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
+                        }
+                        error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
+                    }
+                }
+            }
+        }
+        function checkInheritedPropertiesAreIdentical(type, typeNode) {
+            var baseTypes = getBaseTypes(type);
+            if (baseTypes.length < 2) {
+                return true;
+            }
+            var seen = ts.createUnderscoreEscapedMap();
+            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); });
+            var ok = true;
+            for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) {
+                var base = baseTypes_2[_i];
+                var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
+                for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) {
+                    var prop = properties_8[_a];
+                    var existing = seen.get(prop.escapedName);
+                    if (!existing) {
+                        seen.set(prop.escapedName, { prop: prop, containingType: base });
+                    }
+                    else {
+                        var isInheritedProperty = existing.containingType !== type;
+                        if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
+                            ok = false;
+                            var typeName1 = typeToString(existing.containingType);
+                            var typeName2 = typeToString(base);
+                            var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
+                            errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
+                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
+                        }
+                    }
+                }
+            }
+            return ok;
+        }
+        function checkInterfaceDeclaration(node) {
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
+            checkTypeParameters(node.typeParameters);
+            if (produceDiagnostics) {
+                checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
+                checkExportsOnMergedDeclarations(node);
+                var symbol = getSymbolOfNode(node);
+                checkTypeParameterListsIdentical(symbol);
+                // Only check this symbol once
+                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */);
+                if (node === firstInterfaceDecl) {
+                    var type = getDeclaredTypeOfSymbol(symbol);
+                    var typeWithThis = getTypeWithThisArgument(type);
+                    // run subsequent checks only if first set succeeded
+                    if (checkInheritedPropertiesAreIdentical(type, node.name)) {
+                        for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) {
+                            var baseType = _a[_i];
+                            checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
+                        }
+                        checkIndexConstraints(type);
+                    }
+                }
+                checkObjectTypeForDuplicateDeclarations(node);
+            }
+            ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) {
+                if (!ts.isEntityNameExpression(heritageElement.expression)) {
+                    error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
+                }
+                checkTypeReferenceNode(heritageElement);
+            });
+            ts.forEach(node.members, checkSourceElement);
+            if (produceDiagnostics) {
+                checkTypeForDuplicateIndexSignatures(node);
+                registerForUnusedIdentifiersCheck(node);
+            }
+        }
+        function checkTypeAliasDeclaration(node) {
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node);
+            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
+            checkTypeParameters(node.typeParameters);
+            checkSourceElement(node.type);
+            registerForUnusedIdentifiersCheck(node);
+        }
+        function computeEnumMemberValues(node) {
+            var nodeLinks = getNodeLinks(node);
+            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
+                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
+                var autoValue = 0;
+                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                    var member = _a[_i];
+                    var value = computeMemberValue(member, autoValue);
+                    getNodeLinks(member).enumMemberValue = value;
+                    autoValue = typeof value === "number" ? value + 1 : undefined;
+                }
+            }
+        }
+        function computeMemberValue(member, autoValue) {
+            if (isComputedNonLiteralName(member.name)) {
+                error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
+            }
+            else {
+                var text = ts.getTextOfPropertyName(member.name);
+                if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
+                    error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+                }
+            }
+            if (member.initializer) {
+                return computeConstantValue(member);
+            }
+            // In ambient enum declarations that specify no const modifier, enum member declarations that omit
+            // a value are considered computed members (as opposed to having auto-incremented values).
+            if (ts.isInAmbientContext(member.parent) && !ts.isConst(member.parent)) {
+                return undefined;
+            }
+            // If the member declaration specifies no value, the member is considered a constant enum member.
+            // If the member is the first member in the enum declaration, it is assigned the value zero.
+            // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
+            // occurs if the immediately preceding member is not a constant enum member.
+            if (autoValue !== undefined) {
+                return autoValue;
+            }
+            error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
+            return undefined;
+        }
+        function computeConstantValue(member) {
+            var enumKind = getEnumKind(getSymbolOfNode(member.parent));
+            var isConstEnum = ts.isConst(member.parent);
+            var initializer = member.initializer;
+            var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
+            if (value !== undefined) {
+                if (isConstEnum && typeof value === "number" && !isFinite(value)) {
+                    error(initializer, isNaN(value) ?
+                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
+                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
+                }
+            }
+            else if (enumKind === 1 /* Literal */) {
+                error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
+                return 0;
+            }
+            else if (isConstEnum) {
+                error(initializer, ts.Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
+            }
+            else if (ts.isInAmbientContext(member.parent)) {
+                error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
+            }
+            else {
+                // Only here do we need to check that the initializer is assignable to the enum type.
+                checkTypeAssignableTo(checkExpression(initializer), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
+            }
+            return value;
+            function evaluate(expr) {
+                switch (expr.kind) {
+                    case 192 /* PrefixUnaryExpression */:
+                        var value_1 = evaluate(expr.operand);
+                        if (typeof value_1 === "number") {
+                            switch (expr.operator) {
+                                case 37 /* PlusToken */: return value_1;
+                                case 38 /* MinusToken */: return -value_1;
+                                case 52 /* TildeToken */: return ~value_1;
+                            }
+                        }
+                        break;
+                    case 194 /* BinaryExpression */:
+                        var left = evaluate(expr.left);
+                        var right = evaluate(expr.right);
+                        if (typeof left === "number" && typeof right === "number") {
+                            switch (expr.operatorToken.kind) {
+                                case 49 /* BarToken */: return left | right;
+                                case 48 /* AmpersandToken */: return left & right;
+                                case 46 /* GreaterThanGreaterThanToken */: return left >> right;
+                                case 47 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
+                                case 45 /* LessThanLessThanToken */: return left << right;
+                                case 50 /* CaretToken */: return left ^ right;
+                                case 39 /* AsteriskToken */: return left * right;
+                                case 41 /* SlashToken */: return left / right;
+                                case 37 /* PlusToken */: return left + right;
+                                case 38 /* MinusToken */: return left - right;
+                                case 42 /* PercentToken */: return left % right;
+                            }
+                        }
+                        break;
+                    case 9 /* StringLiteral */:
+                        return expr.text;
+                    case 8 /* NumericLiteral */:
+                        checkGrammarNumericLiteral(expr);
+                        return +expr.text;
+                    case 185 /* ParenthesizedExpression */:
+                        return evaluate(expr.expression);
+                    case 71 /* Identifier */:
+                        return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), expr.escapedText);
+                    case 180 /* ElementAccessExpression */:
+                    case 179 /* PropertyAccessExpression */:
+                        var ex = expr;
+                        if (isConstantMemberAccess(ex)) {
+                            var type = getTypeOfExpression(ex.expression);
+                            if (type.symbol && type.symbol.flags & 384 /* Enum */) {
+                                var name = void 0;
+                                if (ex.kind === 179 /* PropertyAccessExpression */) {
+                                    name = ex.name.escapedText;
+                                }
+                                else {
+                                    var argument = ex.argumentExpression;
+                                    ts.Debug.assert(ts.isLiteralExpression(argument));
+                                    name = ts.escapeLeadingUnderscores(argument.text);
+                                }
+                                return evaluateEnumMember(expr, type.symbol, name);
+                            }
+                        }
+                        break;
+                }
+                return undefined;
+            }
+            function evaluateEnumMember(expr, enumSymbol, name) {
+                var memberSymbol = enumSymbol.exports.get(name);
+                if (memberSymbol) {
+                    var declaration = memberSymbol.valueDeclaration;
+                    if (declaration !== member) {
+                        if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
+                            return getNodeLinks(declaration).enumMemberValue;
+                        }
+                        error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
+                        return 0;
+                    }
+                }
+                return undefined;
+            }
+        }
+        function isConstantMemberAccess(node) {
+            return node.kind === 71 /* Identifier */ ||
+                node.kind === 179 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) ||
+                node.kind === 180 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) &&
+                    node.argumentExpression.kind === 9 /* StringLiteral */;
+        }
+        function checkEnumDeclaration(node) {
+            if (!produceDiagnostics) {
+                return;
+            }
+            // Grammar checking
+            checkGrammarDecorators(node) || checkGrammarModifiers(node);
+            checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
+            checkCollisionWithCapturedThisVariable(node, node.name);
+            checkCollisionWithCapturedNewTargetVariable(node, node.name);
+            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+            checkExportsOnMergedDeclarations(node);
+            computeEnumMemberValues(node);
+            var enumIsConst = ts.isConst(node);
+            if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) {
+                error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided);
+            }
+            // Spec 2014 - Section 9.3:
+            // It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
+            // and when an enum type has multiple declarations, only one declaration is permitted to omit a value
+            // for the first member.
+            //
+            // Only perform this check once per symbol
+            var enumSymbol = getSymbolOfNode(node);
+            var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind);
+            if (node === firstDeclaration) {
+                if (enumSymbol.declarations.length > 1) {
+                    // check that const is placed\omitted on all enum declarations
+                    ts.forEach(enumSymbol.declarations, function (decl) {
+                        if (ts.isConstEnumDeclaration(decl) !== enumIsConst) {
+                            error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
+                        }
+                    });
+                }
+                var seenEnumMissingInitialInitializer_1 = false;
+                ts.forEach(enumSymbol.declarations, function (declaration) {
+                    // return true if we hit a violation of the rule, false otherwise
+                    if (declaration.kind !== 232 /* EnumDeclaration */) {
+                        return false;
+                    }
+                    var enumDeclaration = declaration;
+                    if (!enumDeclaration.members.length) {
+                        return false;
+                    }
+                    var firstEnumMember = enumDeclaration.members[0];
+                    if (!firstEnumMember.initializer) {
+                        if (seenEnumMissingInitialInitializer_1) {
+                            error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
+                        }
+                        else {
+                            seenEnumMissingInitialInitializer_1 = true;
+                        }
+                    }
+                });
+            }
+        }
+        function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
+            var declarations = symbol.declarations;
+            for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
+                var declaration = declarations_7[_i];
+                if ((declaration.kind === 229 /* ClassDeclaration */ ||
+                    (declaration.kind === 228 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) &&
+                    !ts.isInAmbientContext(declaration)) {
+                    return declaration;
+                }
+            }
+            return undefined;
+        }
+        function inSameLexicalScope(node1, node2) {
+            var container1 = ts.getEnclosingBlockScopeContainer(node1);
+            var container2 = ts.getEnclosingBlockScopeContainer(node2);
+            if (isGlobalSourceFile(container1)) {
+                return isGlobalSourceFile(container2);
+            }
+            else if (isGlobalSourceFile(container2)) {
+                return false;
+            }
+            else {
+                return container1 === container2;
+            }
+        }
+        function checkModuleDeclaration(node) {
+            if (produceDiagnostics) {
+                // Grammar checking
+                var isGlobalAugmentation = ts.isGlobalScopeAugmentation(node);
+                var inAmbientContext = ts.isInAmbientContext(node);
+                if (isGlobalAugmentation && !inAmbientContext) {
+                    error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
+                }
+                var isAmbientExternalModule = ts.isAmbientModule(node);
+                var contextErrorMessage = isAmbientExternalModule
+                    ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
+                    : ts.Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
+                if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
+                    // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
+                    return;
+                }
+                if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) {
+                    if (!inAmbientContext && node.name.kind === 9 /* StringLiteral */) {
+                        grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
+                    }
+                }
+                if (ts.isIdentifier(node.name)) {
+                    checkCollisionWithCapturedThisVariable(node, node.name);
+                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+                    checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+                }
+                checkExportsOnMergedDeclarations(node);
+                var symbol = getSymbolOfNode(node);
+                // The following checks only apply on a non-ambient instantiated module declaration.
+                if (symbol.flags & 512 /* ValueModule */
+                    && symbol.declarations.length > 1
+                    && !inAmbientContext
+                    && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) {
+                    var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
+                    if (firstNonAmbientClassOrFunc) {
+                        if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) {
+                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
+                        }
+                        else if (node.pos < firstNonAmbientClassOrFunc.pos) {
+                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
+                        }
+                    }
+                    // if the module merges with a class declaration in the same lexical scope,
+                    // we need to track this to ensure the correct emit.
+                    var mergedClass = ts.getDeclarationOfKind(symbol, 229 /* ClassDeclaration */);
+                    if (mergedClass &&
+                        inSameLexicalScope(node, mergedClass)) {
+                        getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */;
+                    }
+                }
+                if (isAmbientExternalModule) {
+                    if (ts.isExternalModuleAugmentation(node)) {
+                        // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
+                        // otherwise we'll be swamped in cascading errors.
+                        // We can detect if augmentation was applied using following rules:
+                        // - augmentation for a global scope is always applied
+                        // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module).
+                        var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */);
+                        if (checkBody && node.body) {
+                            // body of ambient external module is always a module block
+                            for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) {
+                                var statement = _a[_i];
+                                checkModuleAugmentationElement(statement, isGlobalAugmentation);
+                            }
+                        }
+                    }
+                    else if (isGlobalSourceFile(node.parent)) {
+                        if (isGlobalAugmentation) {
+                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
+                        }
+                        else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) {
+                            error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
+                        }
+                    }
+                    else {
+                        if (isGlobalAugmentation) {
+                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
+                        }
+                        else {
+                            // Node is not an augmentation and is not located on the script level.
+                            // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
+                            error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
+                        }
+                    }
+                }
+            }
+            if (node.body) {
+                checkSourceElement(node.body);
+                if (!ts.isGlobalScopeAugmentation(node)) {
+                    registerForUnusedIdentifiersCheck(node);
+                }
+            }
+        }
+        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
+            switch (node.kind) {
+                case 208 /* VariableStatement */:
+                    // error each individual name in variable statement instead of marking the entire variable statement
+                    for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                        var decl = _a[_i];
+                        checkModuleAugmentationElement(decl, isGlobalAugmentation);
+                    }
+                    break;
+                case 243 /* ExportAssignment */:
+                case 244 /* ExportDeclaration */:
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
+                    break;
+                case 237 /* ImportEqualsDeclaration */:
+                case 238 /* ImportDeclaration */:
+                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
+                    break;
+                case 176 /* BindingElement */:
+                case 226 /* VariableDeclaration */:
+                    var name = node.name;
+                    if (ts.isBindingPattern(name)) {
+                        for (var _b = 0, _c = name.elements; _b < _c.length; _b++) {
+                            var el = _c[_b];
+                            // mark individual names in binding pattern
+                            checkModuleAugmentationElement(el, isGlobalAugmentation);
+                        }
+                        break;
+                    }
+                // falls through
+                case 229 /* ClassDeclaration */:
+                case 232 /* EnumDeclaration */:
+                case 228 /* FunctionDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                case 233 /* ModuleDeclaration */:
+                case 231 /* TypeAliasDeclaration */:
+                    if (isGlobalAugmentation) {
+                        return;
+                    }
+                    var symbol = getSymbolOfNode(node);
+                    if (symbol) {
+                        // module augmentations cannot introduce new names on the top level scope of the module
+                        // this is done it two steps
+                        // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error
+                        // 2. main check - report error if value declaration of the parent symbol is module augmentation)
+                        var reportError = !(symbol.flags & 33554432 /* Transient */);
+                        if (!reportError) {
+                            // symbol should not originate in augmentation
+                            reportError = ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
+                        }
+                    }
+                    break;
+            }
+        }
+        function getFirstIdentifier(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return node;
+                case 143 /* QualifiedName */:
+                    do {
+                        node = node.left;
+                    } while (node.kind !== 71 /* Identifier */);
+                    return node;
+                case 179 /* PropertyAccessExpression */:
+                    do {
+                        node = node.expression;
+                    } while (node.kind !== 71 /* Identifier */);
+                    return node;
+            }
+        }
+        function checkExternalImportOrExportDeclaration(node) {
+            var moduleName = ts.getExternalModuleName(node);
+            if (!ts.nodeIsMissing(moduleName) && moduleName.kind !== 9 /* StringLiteral */) {
+                error(moduleName, ts.Diagnostics.String_literal_expected);
+                return false;
+            }
+            var inAmbientExternalModule = node.parent.kind === 234 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
+            if (node.parent.kind !== 265 /* SourceFile */ && !inAmbientExternalModule) {
+                error(moduleName, node.kind === 244 /* ExportDeclaration */ ?
+                    ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
+                    ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module);
+                return false;
+            }
+            if (inAmbientExternalModule && ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(moduleName))) {
+                // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration
+                // no need to do this again.
+                if (!isTopLevelInExternalModuleAugmentation(node)) {
+                    // TypeScript 1.0 spec (April 2013): 12.1.6
+                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
+                    // other external modules only through top - level external module names.
+                    // Relative external module names are not permitted.
+                    error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name);
+                    return false;
+                }
+            }
+            return true;
+        }
+        function checkAliasSymbol(node) {
+            var symbol = getSymbolOfNode(node);
+            var target = resolveAlias(symbol);
+            if (target !== unknownSymbol) {
+                // For external modules symbol represent local symbol for an alias.
+                // This local symbol will merge any other local declarations (excluding other aliases)
+                // and symbol.flags will contains combined representation for all merged declaration.
+                // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
+                // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
+                // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
+                var excludedMeanings = (symbol.flags & (107455 /* Value */ | 1048576 /* ExportValue */) ? 107455 /* Value */ : 0) |
+                    (symbol.flags & 793064 /* Type */ ? 793064 /* Type */ : 0) |
+                    (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0);
+                if (target.flags & excludedMeanings) {
+                    var message = node.kind === 246 /* ExportSpecifier */ ?
+                        ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
+                        ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
+                    error(node, message, symbolToString(symbol));
+                }
+                // Don't allow to re-export something with no value side when `--isolatedModules` is set.
+                if (compilerOptions.isolatedModules
+                    && node.kind === 246 /* ExportSpecifier */
+                    && !(target.flags & 107455 /* Value */)
+                    && !ts.isInAmbientContext(node)) {
+                    error(node, ts.Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
+                }
+            }
+        }
+        function checkImportBinding(node) {
+            checkCollisionWithCapturedThisVariable(node, node.name);
+            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+            checkAliasSymbol(node);
+        }
+        function checkImportDeclaration(node) {
+            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
+                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
+                return;
+            }
+            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
+                grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers);
+            }
+            if (checkExternalImportOrExportDeclaration(node)) {
+                var importClause = node.importClause;
+                if (importClause) {
+                    if (importClause.name) {
+                        checkImportBinding(importClause);
+                    }
+                    if (importClause.namedBindings) {
+                        if (importClause.namedBindings.kind === 240 /* NamespaceImport */) {
+                            checkImportBinding(importClause.namedBindings);
+                        }
+                        else {
+                            ts.forEach(importClause.namedBindings.elements, checkImportBinding);
+                        }
+                    }
+                }
+            }
+        }
+        function checkImportEqualsDeclaration(node) {
+            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
+                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
+                return;
+            }
+            checkGrammarDecorators(node) || checkGrammarModifiers(node);
+            if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
+                checkImportBinding(node);
+                if (ts.hasModifier(node, 1 /* Export */)) {
+                    markExportAsReferenced(node);
+                }
+                if (ts.isInternalModuleImportEqualsDeclaration(node)) {
+                    var target = resolveAlias(getSymbolOfNode(node));
+                    if (target !== unknownSymbol) {
+                        if (target.flags & 107455 /* Value */) {
+                            // Target is a value symbol, check that it is not hidden by a local declaration with the same name
+                            var moduleName = getFirstIdentifier(node.moduleReference);
+                            if (!(resolveEntityName(moduleName, 107455 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) {
+                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
+                            }
+                        }
+                        if (target.flags & 793064 /* Type */) {
+                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
+                        }
+                    }
+                }
+                else {
+                    if (modulekind >= ts.ModuleKind.ES2015 && !ts.isInAmbientContext(node)) {
+                        // Import equals declaration is deprecated in es6 or above
+                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
+                    }
+                }
+            }
+        }
+        function checkExportDeclaration(node) {
+            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
+                // If we hit an export in an illegal context, just bail out to avoid cascading errors.
+                return;
+            }
+            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
+                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers);
+            }
+            if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
+                if (node.exportClause) {
+                    // export { x, y }
+                    // export { x, y } from "foo"
+                    ts.forEach(node.exportClause.elements, checkExportSpecifier);
+                    var inAmbientExternalModule = node.parent.kind === 234 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
+                    var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 234 /* ModuleBlock */ &&
+                        !node.moduleSpecifier && ts.isInAmbientContext(node);
+                    if (node.parent.kind !== 265 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
+                        error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
+                    }
+                }
+                else {
+                    // export * from "foo"
+                    var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
+                    if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
+                        error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
+                    }
+                    if (modulekind !== ts.ModuleKind.System && modulekind !== ts.ModuleKind.ES2015 && modulekind !== ts.ModuleKind.ESNext) {
+                        checkExternalEmitHelpers(node, 32768 /* ExportStar */);
+                    }
+                }
+            }
+        }
+        function checkGrammarModuleElementContext(node, errorMessage) {
+            var isInAppropriateContext = node.parent.kind === 265 /* SourceFile */ || node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 233 /* ModuleDeclaration */;
+            if (!isInAppropriateContext) {
+                grammarErrorOnFirstToken(node, errorMessage);
+            }
+            return !isInAppropriateContext;
+        }
+        function checkExportSpecifier(node) {
+            checkAliasSymbol(node);
+            if (!node.parent.parent.moduleSpecifier) {
+                var exportedName = node.propertyName || node.name;
+                // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
+                var symbol = resolveName(exportedName, exportedName.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, 
+                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
+                if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
+                    error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName));
+                }
+                else {
+                    markExportAsReferenced(node);
+                }
+            }
+        }
+        function checkExportAssignment(node) {
+            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
+                // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
+                return;
+            }
+            var container = node.parent.kind === 265 /* SourceFile */ ? node.parent : node.parent.parent;
+            if (container.kind === 233 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
+                if (node.isExportEquals) {
+                    error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
+                }
+                else {
+                    error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
+                }
+                return;
+            }
+            // Grammar checking
+            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
+                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
+            }
+            if (node.expression.kind === 71 /* Identifier */) {
+                markExportAsReferenced(node);
+            }
+            else {
+                checkExpressionCached(node.expression);
+            }
+            checkExternalModuleExports(container);
+            if (ts.isInAmbientContext(node) && !ts.isEntityNameExpression(node.expression)) {
+                grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
+            }
+            if (node.isExportEquals && !ts.isInAmbientContext(node)) {
+                if (modulekind >= ts.ModuleKind.ES2015) {
+                    // export assignment is not supported in es6 modules
+                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
+                }
+                else if (modulekind === ts.ModuleKind.System) {
+                    // system modules does not support export assignment
+                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
+                }
+            }
+        }
+        function hasExportedMembers(moduleSymbol) {
+            return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; });
+        }
+        function checkExternalModuleExports(node) {
+            var moduleSymbol = getSymbolOfNode(node);
+            var links = getSymbolLinks(moduleSymbol);
+            if (!links.exportsChecked) {
+                var exportEqualsSymbol = moduleSymbol.exports.get("export=");
+                if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
+                    var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
+                    if (!isTopLevelInExternalModuleAugmentation(declaration)) {
+                        error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
+                    }
+                }
+                // Checks for export * conflicts
+                var exports = getExportsOfModule(moduleSymbol);
+                exports && exports.forEach(function (_a, id) {
+                    var declarations = _a.declarations, flags = _a.flags;
+                    if (id === "__export") {
+                        return;
+                    }
+                    // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
+                    // (TS Exceptions: namespaces, function overloads, enums, and interfaces)
+                    if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
+                        return;
+                    }
+                    var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor);
+                    if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) {
+                        // it is legal to merge type alias with other values
+                        // so count should be either 1 (just type alias) or 2 (type alias + merged value)
+                        return;
+                    }
+                    if (exportedDeclarationsCount > 1) {
+                        for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) {
+                            var declaration = declarations_8[_i];
+                            if (isNotOverload(declaration)) {
+                                diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id)));
+                            }
+                        }
+                    }
+                });
+                links.exportsChecked = true;
+            }
+        }
+        function isNotAccessor(declaration) {
+            // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
+            return !ts.isAccessor(declaration);
+        }
+        function isNotOverload(declaration) {
+            return (declaration.kind !== 228 /* FunctionDeclaration */ && declaration.kind !== 151 /* MethodDeclaration */) ||
+                !!declaration.body;
+        }
+        function checkSourceElement(node) {
+            if (!node) {
+                return;
+            }
+            if (ts.isInJavaScriptFile(node) && node.jsDoc) {
+                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
+                    var tags = _a[_i].tags;
+                    ts.forEach(tags, checkSourceElement);
+                }
+            }
+            var kind = node.kind;
+            if (cancellationToken) {
+                // Only bother checking on a few construct kinds.  We don't want to be excessively
+                // hitting the cancellation token on every node we check.
+                switch (kind) {
+                    case 233 /* ModuleDeclaration */:
+                    case 229 /* ClassDeclaration */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 228 /* FunctionDeclaration */:
+                        cancellationToken.throwIfCancellationRequested();
+                }
+            }
+            switch (kind) {
+                case 145 /* TypeParameter */:
+                    return checkTypeParameter(node);
+                case 146 /* Parameter */:
+                    return checkParameter(node);
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    return checkPropertyDeclaration(node);
+                case 160 /* FunctionType */:
+                case 161 /* ConstructorType */:
+                case 155 /* CallSignature */:
+                case 156 /* ConstructSignature */:
+                    return checkSignatureDeclaration(node);
+                case 157 /* IndexSignature */:
+                    return checkSignatureDeclaration(node);
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                    return checkMethodDeclaration(node);
+                case 152 /* Constructor */:
+                    return checkConstructorDeclaration(node);
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return checkAccessorDeclaration(node);
+                case 159 /* TypeReference */:
+                    return checkTypeReferenceNode(node);
+                case 158 /* TypePredicate */:
+                    return checkTypePredicate(node);
+                case 162 /* TypeQuery */:
+                    return checkTypeQuery(node);
+                case 163 /* TypeLiteral */:
+                    return checkTypeLiteral(node);
+                case 164 /* ArrayType */:
+                    return checkArrayType(node);
+                case 165 /* TupleType */:
+                    return checkTupleType(node);
+                case 166 /* UnionType */:
+                case 167 /* IntersectionType */:
+                    return checkUnionOrIntersectionType(node);
+                case 168 /* ParenthesizedType */:
+                case 170 /* TypeOperator */:
+                    return checkSourceElement(node.type);
+                case 277 /* JSDocAugmentsTag */:
+                    return checkJSDocAugmentsTag(node);
+                case 283 /* JSDocTypedefTag */:
+                    return checkJSDocTypedefTag(node);
+                case 279 /* JSDocParameterTag */:
+                    return checkJSDocParameterTag(node);
+                case 273 /* JSDocFunctionType */:
+                    checkSignatureDeclaration(node);
+                // falls through
+                case 274 /* JSDocVariadicType */:
+                case 271 /* JSDocNonNullableType */:
+                case 270 /* JSDocNullableType */:
+                case 268 /* JSDocAllType */:
+                case 269 /* JSDocUnknownType */:
+                    if (!ts.isInJavaScriptFile(node) && !ts.isInJSDoc(node)) {
+                        grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
+                    }
+                    return;
+                case 267 /* JSDocTypeExpression */:
+                    return checkSourceElement(node.type);
+                case 171 /* IndexedAccessType */:
+                    return checkIndexedAccessType(node);
+                case 172 /* MappedType */:
+                    return checkMappedType(node);
+                case 228 /* FunctionDeclaration */:
+                    return checkFunctionDeclaration(node);
+                case 207 /* Block */:
+                case 234 /* ModuleBlock */:
+                    return checkBlock(node);
+                case 208 /* VariableStatement */:
+                    return checkVariableStatement(node);
+                case 210 /* ExpressionStatement */:
+                    return checkExpressionStatement(node);
+                case 211 /* IfStatement */:
+                    return checkIfStatement(node);
+                case 212 /* DoStatement */:
+                    return checkDoStatement(node);
+                case 213 /* WhileStatement */:
+                    return checkWhileStatement(node);
+                case 214 /* ForStatement */:
+                    return checkForStatement(node);
+                case 215 /* ForInStatement */:
+                    return checkForInStatement(node);
+                case 216 /* ForOfStatement */:
+                    return checkForOfStatement(node);
+                case 217 /* ContinueStatement */:
+                case 218 /* BreakStatement */:
+                    return checkBreakOrContinueStatement(node);
+                case 219 /* ReturnStatement */:
+                    return checkReturnStatement(node);
+                case 220 /* WithStatement */:
+                    return checkWithStatement(node);
+                case 221 /* SwitchStatement */:
+                    return checkSwitchStatement(node);
+                case 222 /* LabeledStatement */:
+                    return checkLabeledStatement(node);
+                case 223 /* ThrowStatement */:
+                    return checkThrowStatement(node);
+                case 224 /* TryStatement */:
+                    return checkTryStatement(node);
+                case 226 /* VariableDeclaration */:
+                    return checkVariableDeclaration(node);
+                case 176 /* BindingElement */:
+                    return checkBindingElement(node);
+                case 229 /* ClassDeclaration */:
+                    return checkClassDeclaration(node);
+                case 230 /* InterfaceDeclaration */:
+                    return checkInterfaceDeclaration(node);
+                case 231 /* TypeAliasDeclaration */:
+                    return checkTypeAliasDeclaration(node);
+                case 232 /* EnumDeclaration */:
+                    return checkEnumDeclaration(node);
+                case 233 /* ModuleDeclaration */:
+                    return checkModuleDeclaration(node);
+                case 238 /* ImportDeclaration */:
+                    return checkImportDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return checkImportEqualsDeclaration(node);
+                case 244 /* ExportDeclaration */:
+                    return checkExportDeclaration(node);
+                case 243 /* ExportAssignment */:
+                    return checkExportAssignment(node);
+                case 209 /* EmptyStatement */:
+                    checkGrammarStatementInAmbientContext(node);
+                    return;
+                case 225 /* DebuggerStatement */:
+                    checkGrammarStatementInAmbientContext(node);
+                    return;
+                case 247 /* MissingDeclaration */:
+                    return checkMissingDeclaration(node);
+            }
+        }
+        // Function and class expression bodies are checked after all statements in the enclosing body. This is
+        // to ensure constructs like the following are permitted:
+        //     const foo = function () {
+        //        const s = foo();
+        //        return "hello";
+        //     }
+        // Here, performing a full type check of the body of the function expression whilst in the process of
+        // determining the type of foo would cause foo to be given type any because of the recursive reference.
+        // Delaying the type check of the body ensures foo has been assigned a type.
+        function checkNodeDeferred(node) {
+            if (deferredNodes) {
+                deferredNodes.push(node);
+            }
+        }
+        function checkDeferredNodes() {
+            for (var _i = 0, deferredNodes_1 = deferredNodes; _i < deferredNodes_1.length; _i++) {
+                var node = deferredNodes_1[_i];
+                switch (node.kind) {
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
+                        break;
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        checkAccessorDeclaration(node);
+                        break;
+                    case 199 /* ClassExpression */:
+                        checkClassExpressionDeferred(node);
+                        break;
+                }
+            }
+        }
+        function checkSourceFile(node) {
+            ts.performance.mark("beforeCheck");
+            checkSourceFileWorker(node);
+            ts.performance.mark("afterCheck");
+            ts.performance.measure("Check", "beforeCheck", "afterCheck");
+        }
+        // Fully type check a source file and collect the relevant diagnostics.
+        function checkSourceFileWorker(node) {
+            var links = getNodeLinks(node);
+            if (!(links.flags & 1 /* TypeChecked */)) {
+                // If skipLibCheck is enabled, skip type checking if file is a declaration file.
+                // If skipDefaultLibCheck is enabled, skip type checking if file contains a
+                // '/// <reference no-default-lib="true"/>' directive.
+                if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) {
+                    return;
+                }
+                // Grammar checking
+                checkGrammarSourceFile(node);
+                ts.clear(potentialThisCollisions);
+                ts.clear(potentialNewTargetCollisions);
+                deferredNodes = [];
+                deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
+                flowAnalysisDisabled = false;
+                ts.forEach(node.statements, checkSourceElement);
+                checkDeferredNodes();
+                if (ts.isExternalModule(node)) {
+                    registerForUnusedIdentifiersCheck(node);
+                }
+                if (!node.isDeclarationFile) {
+                    checkUnusedIdentifiers();
+                }
+                deferredNodes = undefined;
+                deferredUnusedIdentifierNodes = undefined;
+                if (ts.isExternalOrCommonJsModule(node)) {
+                    checkExternalModuleExports(node);
+                }
+                if (potentialThisCollisions.length) {
+                    ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
+                    ts.clear(potentialThisCollisions);
+                }
+                if (potentialNewTargetCollisions.length) {
+                    ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
+                    ts.clear(potentialNewTargetCollisions);
+                }
+                links.flags |= 1 /* TypeChecked */;
+            }
+        }
+        function getDiagnostics(sourceFile, ct) {
+            try {
+                // Record the cancellation token so it can be checked later on during checkSourceElement.
+                // Do this in a finally block so we can ensure that it gets reset back to nothing after
+                // this call is done.
+                cancellationToken = ct;
+                return getDiagnosticsWorker(sourceFile);
+            }
+            finally {
+                cancellationToken = undefined;
+            }
+        }
+        function getDiagnosticsWorker(sourceFile) {
+            throwIfNonDiagnosticsProducing();
+            if (sourceFile) {
+                // Some global diagnostics are deferred until they are needed and
+                // may not be reported in the firt call to getGlobalDiagnostics.
+                // We should catch these changes and report them.
+                var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
+                var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
+                checkSourceFile(sourceFile);
+                var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
+                var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
+                if (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
+                    // If the arrays are not the same reference, new diagnostics were added.
+                    var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics);
+                    return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics);
+                }
+                else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) {
+                    // If the arrays are the same reference, but the length has changed, a single
+                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
+                    // same array.
+                    return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics);
+                }
+                return semanticDiagnostics;
+            }
+            // Global diagnostics are always added when a file is not provided to
+            // getDiagnostics
+            ts.forEach(host.getSourceFiles(), checkSourceFile);
+            return diagnostics.getDiagnostics();
+        }
+        function getGlobalDiagnostics() {
+            throwIfNonDiagnosticsProducing();
+            return diagnostics.getGlobalDiagnostics();
+        }
+        function throwIfNonDiagnosticsProducing() {
+            if (!produceDiagnostics) {
+                throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
+            }
+        }
+        // Language service support
+        function isInsideWithStatementBody(node) {
+            if (node) {
+                while (node.parent) {
+                    if (node.parent.kind === 220 /* WithStatement */ && node.parent.statement === node) {
+                        return true;
+                    }
+                    node = node.parent;
+                }
+            }
+            return false;
+        }
+        function getSymbolsInScope(location, meaning) {
+            if (isInsideWithStatementBody(location)) {
+                // We cannot answer semantic questions within a with block, do not proceed any further
+                return [];
+            }
+            var symbols = ts.createSymbolTable();
+            var isStatic = false;
+            populateSymbols();
+            return symbolsToArray(symbols);
+            function populateSymbols() {
+                while (location) {
+                    if (location.locals && !isGlobalSourceFile(location)) {
+                        copySymbols(location.locals, meaning);
+                    }
+                    switch (location.kind) {
+                        case 233 /* ModuleDeclaration */:
+                            copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */);
+                            break;
+                        case 232 /* EnumDeclaration */:
+                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
+                            break;
+                        case 199 /* ClassExpression */:
+                            var className = location.name;
+                            if (className) {
+                                copySymbol(location.symbol, meaning);
+                            }
+                        // falls through
+                        // this fall-through is necessary because we would like to handle
+                        // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
+                        case 229 /* ClassDeclaration */:
+                        case 230 /* InterfaceDeclaration */:
+                            // If we didn't come from static member of class or interface,
+                            // add the type parameters into the symbol table
+                            // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
+                            // Note: that the memberFlags come from previous iteration.
+                            if (!isStatic) {
+                                copySymbols(getSymbolOfNode(location).members, meaning & 793064 /* Type */);
+                            }
+                            break;
+                        case 186 /* FunctionExpression */:
+                            var funcName = location.name;
+                            if (funcName) {
+                                copySymbol(location.symbol, meaning);
+                            }
+                            break;
+                    }
+                    if (ts.introducesArgumentsExoticObject(location)) {
+                        copySymbol(argumentsSymbol, meaning);
+                    }
+                    isStatic = ts.hasModifier(location, 32 /* Static */);
+                    location = location.parent;
+                }
+                copySymbols(globals, meaning);
+            }
+            /**
+             * Copy the given symbol into symbol tables if the symbol has the given meaning
+             * and it doesn't already existed in the symbol table
+             * @param key a key for storing in symbol table; if undefined, use symbol.name
+             * @param symbol the symbol to be added into symbol table
+             * @param meaning meaning of symbol to filter by before adding to symbol table
+             */
+            function copySymbol(symbol, meaning) {
+                if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) {
+                    var id = symbol.escapedName;
+                    // We will copy all symbol regardless of its reserved name because
+                    // symbolsToArray will check whether the key is a reserved name and
+                    // it will not copy symbol with reserved name to the array
+                    if (!symbols.has(id)) {
+                        symbols.set(id, symbol);
+                    }
+                }
+            }
+            function copySymbols(source, meaning) {
+                if (meaning) {
+                    source.forEach(function (symbol) {
+                        copySymbol(symbol, meaning);
+                    });
+                }
+            }
+        }
+        function isTypeDeclarationName(name) {
+            return name.kind === 71 /* Identifier */ &&
+                isTypeDeclaration(name.parent) &&
+                name.parent.name === name;
+        }
+        function isTypeDeclaration(node) {
+            switch (node.kind) {
+                case 145 /* TypeParameter */:
+                case 229 /* ClassDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                case 231 /* TypeAliasDeclaration */:
+                case 232 /* EnumDeclaration */:
+                    return true;
+            }
+        }
+        // True if the given identifier is part of a type reference
+        function isTypeReferenceIdentifier(entityName) {
+            var node = entityName;
+            while (node.parent && node.parent.kind === 143 /* QualifiedName */) {
+                node = node.parent;
+            }
+            return node.parent && node.parent.kind === 159 /* TypeReference */;
+        }
+        function isHeritageClauseElementIdentifier(entityName) {
+            var node = entityName;
+            while (node.parent && node.parent.kind === 179 /* PropertyAccessExpression */) {
+                node = node.parent;
+            }
+            return node.parent && node.parent.kind === 201 /* ExpressionWithTypeArguments */;
+        }
+        function forEachEnclosingClass(node, callback) {
+            var result;
+            while (true) {
+                node = ts.getContainingClass(node);
+                if (!node)
+                    break;
+                if (result = callback(node))
+                    break;
+            }
+            return result;
+        }
+        function isNodeWithinClass(node, classDeclaration) {
+            return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; });
+        }
+        function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) {
+            while (nodeOnRightSide.parent.kind === 143 /* QualifiedName */) {
+                nodeOnRightSide = nodeOnRightSide.parent;
+            }
+            if (nodeOnRightSide.parent.kind === 237 /* ImportEqualsDeclaration */) {
+                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide && nodeOnRightSide.parent;
+            }
+            if (nodeOnRightSide.parent.kind === 243 /* ExportAssignment */) {
+                return nodeOnRightSide.parent.expression === nodeOnRightSide && nodeOnRightSide.parent;
+            }
+            return undefined;
+        }
+        function isInRightSideOfImportOrExportAssignment(node) {
+            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
+        }
+        function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) {
+            var specialPropertyAssignmentKind = ts.getSpecialPropertyAssignmentKind(entityName.parent.parent);
+            switch (specialPropertyAssignmentKind) {
+                case 1 /* ExportsProperty */:
+                case 3 /* PrototypeProperty */:
+                    return getSymbolOfNode(entityName.parent);
+                case 4 /* ThisProperty */:
+                case 2 /* ModuleExports */:
+                case 5 /* Property */:
+                    return getSymbolOfNode(entityName.parent.parent);
+            }
+        }
+        function getSymbolOfEntityNameOrPropertyAccessExpression(entityName) {
+            if (ts.isDeclarationName(entityName)) {
+                return getSymbolOfNode(entityName.parent);
+            }
+            if (ts.isInJavaScriptFile(entityName) &&
+                entityName.parent.kind === 179 /* PropertyAccessExpression */ &&
+                entityName.parent === entityName.parent.parent.left) {
+                // Check if this is a special property assignment
+                var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName);
+                if (specialPropertyAssignmentSymbol) {
+                    return specialPropertyAssignmentSymbol;
+                }
+            }
+            if (entityName.parent.kind === 243 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) {
+                return resolveEntityName(entityName, 
+                /*all meanings*/ 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
+            }
+            if (entityName.kind !== 179 /* PropertyAccessExpression */ && isInRightSideOfImportOrExportAssignment(entityName)) {
+                // Since we already checked for ExportAssignment, this really could only be an Import
+                var importEqualsDeclaration = ts.getAncestor(entityName, 237 /* ImportEqualsDeclaration */);
+                ts.Debug.assert(importEqualsDeclaration !== undefined);
+                return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true);
+            }
+            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
+                entityName = entityName.parent;
+            }
+            if (isHeritageClauseElementIdentifier(entityName)) {
+                var meaning = 0 /* None */;
+                // In an interface or class, we're definitely interested in a type.
+                if (entityName.parent.kind === 201 /* ExpressionWithTypeArguments */) {
+                    meaning = 793064 /* Type */;
+                    // In a class 'extends' clause we are also looking for a value.
+                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
+                        meaning |= 107455 /* Value */;
+                    }
+                }
+                else {
+                    meaning = 1920 /* Namespace */;
+                }
+                meaning |= 2097152 /* Alias */;
+                var entityNameSymbol = resolveEntityName(entityName, meaning);
+                if (entityNameSymbol) {
+                    return entityNameSymbol;
+                }
+            }
+            if (entityName.parent.kind === 279 /* JSDocParameterTag */) {
+                return ts.getParameterSymbolFromJSDoc(entityName.parent);
+            }
+            if (entityName.parent.kind === 145 /* TypeParameter */ && entityName.parent.parent.kind === 282 /* JSDocTemplateTag */) {
+                ts.Debug.assert(!ts.isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true.
+                var typeParameter = ts.getTypeParameterFromJsDoc(entityName.parent);
+                return typeParameter && typeParameter.symbol;
+            }
+            if (ts.isPartOfExpression(entityName)) {
+                if (ts.nodeIsMissing(entityName)) {
+                    // Missing entity name.
+                    return undefined;
+                }
+                if (entityName.kind === 71 /* Identifier */) {
+                    if (ts.isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) {
+                        return getIntrinsicTagSymbol(entityName.parent);
+                    }
+                    return resolveEntityName(entityName, 107455 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
+                }
+                else if (entityName.kind === 179 /* PropertyAccessExpression */ || entityName.kind === 143 /* QualifiedName */) {
+                    var links = getNodeLinks(entityName);
+                    if (links.resolvedSymbol) {
+                        return links.resolvedSymbol;
+                    }
+                    if (entityName.kind === 179 /* PropertyAccessExpression */) {
+                        checkPropertyAccessExpression(entityName);
+                    }
+                    else {
+                        checkQualifiedName(entityName);
+                    }
+                    return links.resolvedSymbol;
+                }
+            }
+            else if (isTypeReferenceIdentifier(entityName)) {
+                var meaning = entityName.parent.kind === 159 /* TypeReference */ ? 793064 /* Type */ : 1920 /* Namespace */;
+                return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
+            }
+            else if (entityName.parent.kind === 253 /* JsxAttribute */) {
+                return getJsxAttributePropertySymbol(entityName.parent);
+            }
+            if (entityName.parent.kind === 158 /* TypePredicate */) {
+                return resolveEntityName(entityName, /*meaning*/ 1 /* FunctionScopedVariable */);
+            }
+            // Do we want to return undefined here?
+            return undefined;
+        }
+        function getSymbolAtLocation(node) {
+            if (node.kind === 265 /* SourceFile */) {
+                return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined;
+            }
+            if (isInsideWithStatementBody(node)) {
+                // We cannot answer semantic questions within a with block, do not proceed any further
+                return undefined;
+            }
+            if (isDeclarationNameOrImportPropertyName(node)) {
+                // This is a declaration, call getSymbolOfNode
+                return getSymbolOfNode(node.parent);
+            }
+            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
+                return getSymbolOfNode(node.parent.parent);
+            }
+            if (node.kind === 71 /* Identifier */) {
+                if (isInRightSideOfImportOrExportAssignment(node)) {
+                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
+                }
+                else if (node.parent.kind === 176 /* BindingElement */ &&
+                    node.parent.parent.kind === 174 /* ObjectBindingPattern */ &&
+                    node === node.parent.propertyName) {
+                    var typeOfPattern = getTypeOfNode(node.parent.parent);
+                    var propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, node.escapedText);
+                    if (propertyDeclaration) {
+                        return propertyDeclaration;
+                    }
+                }
+            }
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                case 179 /* PropertyAccessExpression */:
+                case 143 /* QualifiedName */:
+                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
+                case 99 /* ThisKeyword */:
+                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
+                    if (ts.isFunctionLike(container)) {
+                        var sig = getSignatureFromDeclaration(container);
+                        if (sig.thisParameter) {
+                            return sig.thisParameter;
+                        }
+                    }
+                    if (ts.isInExpressionContext(node)) {
+                        return checkExpression(node).symbol;
+                    }
+                // falls through
+                case 169 /* ThisType */:
+                    return getTypeFromThisTypeNode(node).symbol;
+                case 97 /* SuperKeyword */:
+                    return checkExpression(node).symbol;
+                case 123 /* ConstructorKeyword */:
+                    // constructor keyword for an overload, should take us to the definition if it exist
+                    var constructorDeclaration = node.parent;
+                    if (constructorDeclaration && constructorDeclaration.kind === 152 /* Constructor */) {
+                        return constructorDeclaration.parent.symbol;
+                    }
+                    return undefined;
+                case 9 /* StringLiteral */:
+                    // 1). import x = require("./mo/*gotToDefinitionHere*/d")
+                    // 2). External module name in an import declaration
+                    // 3). Dynamic import call or require in javascript
+                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
+                        ((node.parent.kind === 238 /* ImportDeclaration */ || node.parent.kind === 244 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) ||
+                        ((ts.isInJavaScriptFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) || ts.isImportCall(node.parent))) {
+                        return resolveExternalModuleName(node, node);
+                    }
+                // falls through
+                case 8 /* NumericLiteral */:
+                    // index access
+                    var objectType = ts.isElementAccessExpression(node.parent)
+                        ? node.parent.argumentExpression === node ? getTypeOfExpression(node.parent.expression) : undefined
+                        : ts.isLiteralTypeNode(node.parent) && ts.isIndexedAccessTypeNode(node.parent.parent)
+                            ? getTypeFromTypeNode(node.parent.parent.objectType)
+                            : undefined;
+                    return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text));
+                case 79 /* DefaultKeyword */:
+                    return getSymbolOfNode(node.parent);
+                default:
+                    return undefined;
+            }
+        }
+        function getShorthandAssignmentValueSymbol(location) {
+            // The function returns a value symbol of an identifier in the short-hand property assignment.
+            // This is necessary as an identifier in short-hand property assignment can contains two meaning:
+            // property name and property value.
+            if (location && location.kind === 262 /* ShorthandPropertyAssignment */) {
+                return resolveEntityName(location.name, 107455 /* Value */ | 2097152 /* Alias */);
+            }
+            return undefined;
+        }
+        /** Returns the target of an export specifier without following aliases */
+        function getExportSpecifierLocalTargetSymbol(node) {
+            return node.parent.parent.moduleSpecifier ?
+                getExternalModuleMember(node.parent.parent, node) :
+                resolveEntityName(node.propertyName || node.name, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
+        }
+        function getTypeOfNode(node) {
+            if (isInsideWithStatementBody(node)) {
+                // We cannot answer semantic questions within a with block, do not proceed any further
+                return unknownType;
+            }
+            if (ts.isPartOfTypeNode(node)) {
+                var typeFromTypeNode = getTypeFromTypeNode(node);
+                if (typeFromTypeNode && ts.isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
+                    var containingClass = ts.getContainingClass(node);
+                    var classType = getTypeOfNode(containingClass);
+                    typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
+                }
+                return typeFromTypeNode;
+            }
+            if (ts.isPartOfExpression(node)) {
+                return getRegularTypeOfExpression(node);
+            }
+            if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
+                // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
+                // extends clause of a class. We handle that case here.
+                var classNode = ts.getContainingClass(node);
+                var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode));
+                var baseType = getBaseTypes(classType)[0];
+                return baseType && getTypeWithThisArgument(baseType, classType.thisType);
+            }
+            if (isTypeDeclaration(node)) {
+                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
+                var symbol = getSymbolOfNode(node);
+                return getDeclaredTypeOfSymbol(symbol);
+            }
+            if (isTypeDeclarationName(node)) {
+                var symbol = getSymbolAtLocation(node);
+                return symbol && getDeclaredTypeOfSymbol(symbol);
+            }
+            if (ts.isDeclaration(node)) {
+                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
+                var symbol = getSymbolOfNode(node);
+                return getTypeOfSymbol(symbol);
+            }
+            if (isDeclarationNameOrImportPropertyName(node)) {
+                var symbol = getSymbolAtLocation(node);
+                return symbol && getTypeOfSymbol(symbol);
+            }
+            if (ts.isBindingPattern(node)) {
+                return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true);
+            }
+            if (isInRightSideOfImportOrExportAssignment(node)) {
+                var symbol = getSymbolAtLocation(node);
+                var declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
+                return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
+            }
+            return unknownType;
+        }
+        // Gets the type of object literal or array literal of destructuring assignment.
+        // { a } from
+        //     for ( { a } of elems) {
+        //     }
+        // [ a ] from
+        //     [a] = [ some array ...]
+        function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr) {
+            ts.Debug.assert(expr.kind === 178 /* ObjectLiteralExpression */ || expr.kind === 177 /* ArrayLiteralExpression */);
+            // If this is from "for of"
+            //     for ( { a } of elems) {
+            //     }
+            if (expr.parent.kind === 216 /* ForOfStatement */) {
+                var iteratedType = checkRightHandSideOfForOf(expr.parent.expression, expr.parent.awaitModifier);
+                return checkDestructuringAssignment(expr, iteratedType || unknownType);
+            }
+            // If this is from "for" initializer
+            //     for ({a } = elems[0];.....) { }
+            if (expr.parent.kind === 194 /* BinaryExpression */) {
+                var iteratedType = getTypeOfExpression(expr.parent.right);
+                return checkDestructuringAssignment(expr, iteratedType || unknownType);
+            }
+            // If this is from nested object binding pattern
+            //     for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
+            if (expr.parent.kind === 261 /* PropertyAssignment */) {
+                var typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent.parent);
+                return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || unknownType, expr.parent);
+            }
+            // Array literal assignment - array destructuring pattern
+            ts.Debug.assert(expr.parent.kind === 177 /* ArrayLiteralExpression */);
+            //    [{ property1: p1, property2 }] = elems;
+            var typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent);
+            var elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType;
+            return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, ts.indexOf(expr.parent.elements, expr), elementType || unknownType);
+        }
+        // Gets the property symbol corresponding to the property in destructuring assignment
+        // 'property1' from
+        //     for ( { property1: a } of elems) {
+        //     }
+        // 'property1' at location 'a' from:
+        //     [a] = [ property1, property2 ]
+        function getPropertySymbolOfDestructuringAssignment(location) {
+            // Get the type of the object or array literal and then look for property of given name in the type
+            var typeOfObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(location.parent.parent);
+            return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
+        }
+        function getRegularTypeOfExpression(expr) {
+            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
+                expr = expr.parent;
+            }
+            return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
+        }
+        /**
+         * Gets either the static or instance type of a class element, based on
+         * whether the element is declared as "static".
+         */
+        function getParentTypeOfClassElement(node) {
+            var classSymbol = getSymbolOfNode(node.parent);
+            return ts.hasModifier(node, 32 /* Static */)
+                ? getTypeOfSymbol(classSymbol)
+                : getDeclaredTypeOfSymbol(classSymbol);
+        }
+        // Return the list of properties of the given type, augmented with properties from Function
+        // if the type has call or construct signatures
+        function getAugmentedPropertiesOfType(type) {
+            type = getApparentType(type);
+            var propsByName = ts.createSymbolTable(getPropertiesOfType(type));
+            if (getSignaturesOfType(type, 0 /* Call */).length || getSignaturesOfType(type, 1 /* Construct */).length) {
+                ts.forEach(getPropertiesOfType(globalFunctionType), function (p) {
+                    if (!propsByName.has(p.escapedName)) {
+                        propsByName.set(p.escapedName, p);
+                    }
+                });
+            }
+            return getNamedMembers(propsByName);
+        }
+        function getRootSymbols(symbol) {
+            if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) {
+                var symbols_4 = [];
+                var name_3 = symbol.escapedName;
+                ts.forEach(getSymbolLinks(symbol).containingType.types, function (t) {
+                    var symbol = getPropertyOfType(t, name_3);
+                    if (symbol) {
+                        symbols_4.push(symbol);
+                    }
+                });
+                return symbols_4;
+            }
+            else if (symbol.flags & 33554432 /* Transient */) {
+                var transient = symbol;
+                if (transient.leftSpread) {
+                    return getRootSymbols(transient.leftSpread).concat(getRootSymbols(transient.rightSpread));
+                }
+                if (transient.syntheticOrigin) {
+                    return getRootSymbols(transient.syntheticOrigin);
+                }
+                var target = void 0;
+                var next = symbol;
+                while (next = getSymbolLinks(next).target) {
+                    target = next;
+                }
+                if (target) {
+                    return [target];
+                }
+            }
+            return [symbol];
+        }
+        // Emitter support
+        function isArgumentsLocalBinding(node) {
+            if (!ts.isGeneratedIdentifier(node)) {
+                node = ts.getParseTreeNode(node, ts.isIdentifier);
+                if (node) {
+                    var isPropertyName_1 = node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node;
+                    return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol;
+                }
+            }
+            return false;
+        }
+        function moduleExportsSomeValue(moduleReferenceExpression) {
+            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
+            if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
+                // If the module is not found or is shorthand, assume that it may export a value.
+                return true;
+            }
+            var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
+            // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
+            // otherwise it will return moduleSymbol itself
+            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
+            var symbolLinks = getSymbolLinks(moduleSymbol);
+            if (symbolLinks.exportsSomeValue === undefined) {
+                // for export assignments - check if resolved symbol for RHS is itself a value
+                // otherwise - check if at least one export is value
+                symbolLinks.exportsSomeValue = hasExportAssignment
+                    ? !!(moduleSymbol.flags & 107455 /* Value */)
+                    : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue);
+            }
+            return symbolLinks.exportsSomeValue;
+            function isValue(s) {
+                s = resolveSymbol(s);
+                return s && !!(s.flags & 107455 /* Value */);
+            }
+        }
+        function isNameOfModuleOrEnumDeclaration(node) {
+            var parent = node.parent;
+            return parent && ts.isModuleOrEnumDeclaration(parent) && node === parent.name;
+        }
+        // When resolved as an expression identifier, if the given node references an exported entity, return the declaration
+        // node of the exported entity's container. Otherwise, return undefined.
+        function getReferencedExportContainer(node, prefixLocals) {
+            node = ts.getParseTreeNode(node, ts.isIdentifier);
+            if (node) {
+                // When resolving the export container for the name of a module or enum
+                // declaration, we need to start resolution at the declaration's container.
+                // Otherwise, we could incorrectly resolve the export container as the
+                // declaration if it contains an exported member with the same name.
+                var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node));
+                if (symbol) {
+                    if (symbol.flags & 1048576 /* ExportValue */) {
+                        // If we reference an exported entity within the same module declaration, then whether
+                        // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
+                        // kinds that we do NOT prefix.
+                        var exportSymbol = getMergedSymbol(symbol.exportSymbol);
+                        if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */) {
+                            return undefined;
+                        }
+                        symbol = exportSymbol;
+                    }
+                    var parentSymbol_1 = getParentOfSymbol(symbol);
+                    if (parentSymbol_1) {
+                        if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 265 /* SourceFile */) {
+                            var symbolFile = parentSymbol_1.valueDeclaration;
+                            var referenceFile = ts.getSourceFileOfNode(node);
+                            // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
+                            var symbolIsUmdExport = symbolFile !== referenceFile;
+                            return symbolIsUmdExport ? undefined : symbolFile;
+                        }
+                        return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; });
+                    }
+                }
+            }
+        }
+        // When resolved as an expression identifier, if the given node references an import, return the declaration of
+        // that import. Otherwise, return undefined.
+        function getReferencedImportDeclaration(node) {
+            node = ts.getParseTreeNode(node, ts.isIdentifier);
+            if (node) {
+                var symbol = getReferencedValueSymbol(node);
+                // We should only get the declaration of an alias if there isn't a local value
+                // declaration for the symbol
+                if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */)) {
+                    return getDeclarationOfAliasSymbol(symbol);
+                }
+            }
+            return undefined;
+        }
+        function isSymbolOfDeclarationWithCollidingName(symbol) {
+            if (symbol.flags & 418 /* BlockScoped */) {
+                var links = getSymbolLinks(symbol);
+                if (links.isDeclarationWithCollidingName === undefined) {
+                    var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
+                    if (ts.isStatementWithLocals(container)) {
+                        var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration);
+                        if (resolveName(container.parent, symbol.escapedName, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
+                            // redeclaration - always should be renamed
+                            links.isDeclarationWithCollidingName = true;
+                        }
+                        else if (nodeLinks_1.flags & 131072 /* CapturedBlockScopedBinding */) {
+                            // binding is captured in the function
+                            // should be renamed if:
+                            // - binding is not top level - top level bindings never collide with anything
+                            // AND
+                            //   - binding is not declared in loop, should be renamed to avoid name reuse across siblings
+                            //     let a, b
+                            //     { let x = 1; a = () => x;  }
+                            //     { let x = 100; b = () => x; }
+                            //     console.log(a()); // should print '1'
+                            //     console.log(b()); // should print '100'
+                            //     OR
+                            //   - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body
+                            //     * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
+                            //     * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
+                            //       they will not collide with anything
+                            var isDeclaredInLoop = nodeLinks_1.flags & 262144 /* BlockScopedBindingInLoop */;
+                            var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false);
+                            var inLoopBodyBlock = container.kind === 207 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
+                            links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock));
+                        }
+                        else {
+                            links.isDeclarationWithCollidingName = false;
+                        }
+                    }
+                }
+                return links.isDeclarationWithCollidingName;
+            }
+            return false;
+        }
+        // When resolved as an expression identifier, if the given node references a nested block scoped entity with
+        // a name that either hides an existing name or might hide it when compiled downlevel,
+        // return the declaration of that entity. Otherwise, return undefined.
+        function getReferencedDeclarationWithCollidingName(node) {
+            if (!ts.isGeneratedIdentifier(node)) {
+                node = ts.getParseTreeNode(node, ts.isIdentifier);
+                if (node) {
+                    var symbol = getReferencedValueSymbol(node);
+                    if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
+                        return symbol.valueDeclaration;
+                    }
+                }
+            }
+            return undefined;
+        }
+        // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
+        // existing name or might hide a name when compiled downlevel
+        function isDeclarationWithCollidingName(node) {
+            node = ts.getParseTreeNode(node, ts.isDeclaration);
+            if (node) {
+                var symbol = getSymbolOfNode(node);
+                if (symbol) {
+                    return isSymbolOfDeclarationWithCollidingName(symbol);
+                }
+            }
+            return false;
+        }
+        function isValueAliasDeclaration(node) {
+            switch (node.kind) {
+                case 237 /* ImportEqualsDeclaration */:
+                case 239 /* ImportClause */:
+                case 240 /* NamespaceImport */:
+                case 242 /* ImportSpecifier */:
+                case 246 /* ExportSpecifier */:
+                    return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
+                case 244 /* ExportDeclaration */:
+                    var exportClause = node.exportClause;
+                    return exportClause && ts.forEach(exportClause.elements, isValueAliasDeclaration);
+                case 243 /* ExportAssignment */:
+                    return node.expression
+                        && node.expression.kind === 71 /* Identifier */
+                        ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol)
+                        : true;
+            }
+            return false;
+        }
+        function isTopLevelValueImportEqualsWithEntityName(node) {
+            node = ts.getParseTreeNode(node, ts.isImportEqualsDeclaration);
+            if (node === undefined || node.parent.kind !== 265 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) {
+                // parent is not source file or it is not reference to internal module
+                return false;
+            }
+            var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
+            return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference);
+        }
+        function isAliasResolvedToValue(symbol) {
+            var target = resolveAlias(symbol);
+            if (target === unknownSymbol) {
+                return true;
+            }
+            // const enums and modules that contain only const enums are not considered values from the emit perspective
+            // unless 'preserveConstEnums' option is set to true
+            return target.flags & 107455 /* Value */ &&
+                (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
+        }
+        function isConstEnumOrConstEnumOnlyModule(s) {
+            return isConstEnumSymbol(s) || s.constEnumOnlyModule;
+        }
+        function isReferencedAliasDeclaration(node, checkChildren) {
+            if (ts.isAliasSymbolDeclaration(node)) {
+                var symbol = getSymbolOfNode(node);
+                if (symbol && getSymbolLinks(symbol).referenced) {
+                    return true;
+                }
+            }
+            if (checkChildren) {
+                return ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); });
+            }
+            return false;
+        }
+        function isImplementationOfOverload(node) {
+            if (ts.nodeIsPresent(node.body)) {
+                var symbol = getSymbolOfNode(node);
+                var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
+                // If this function body corresponds to function with multiple signature, it is implementation of overload
+                // e.g.: function foo(a: string): string;
+                //       function foo(a: number): number;
+                //       function foo(a: any) { // This is implementation of the overloads
+                //           return a;
+                //       }
+                return signaturesOfSymbol.length > 1 ||
+                    // If there is single signature for the symbol, it is overload if that signature isn't coming from the node
+                    // e.g.: function foo(a: string): string;
+                    //       function foo(a: any) { // This is implementation of the overloads
+                    //           return a;
+                    //       }
+                    (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
+            }
+            return false;
+        }
+        function isRequiredInitializedParameter(parameter) {
+            return strictNullChecks &&
+                !isOptionalParameter(parameter) &&
+                parameter.initializer &&
+                !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
+        }
+        function isOptionalUninitializedParameterProperty(parameter) {
+            return strictNullChecks &&
+                isOptionalParameter(parameter) &&
+                !parameter.initializer &&
+                ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
+        }
+        function getNodeCheckFlags(node) {
+            return getNodeLinks(node).flags;
+        }
+        function getEnumMemberValue(node) {
+            computeEnumMemberValues(node.parent);
+            return getNodeLinks(node).enumMemberValue;
+        }
+        function canHaveConstantValue(node) {
+            switch (node.kind) {
+                case 264 /* EnumMember */:
+                case 179 /* PropertyAccessExpression */:
+                case 180 /* ElementAccessExpression */:
+                    return true;
+            }
+            return false;
+        }
+        function getConstantValue(node) {
+            if (node.kind === 264 /* EnumMember */) {
+                return getEnumMemberValue(node);
+            }
+            var symbol = getNodeLinks(node).resolvedSymbol;
+            if (symbol && (symbol.flags & 8 /* EnumMember */)) {
+                // inline property\index accesses only for const enums
+                if (ts.isConstEnumDeclaration(symbol.valueDeclaration.parent)) {
+                    return getEnumMemberValue(symbol.valueDeclaration);
+                }
+            }
+            return undefined;
+        }
+        function isFunctionType(type) {
+            return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0;
+        }
+        function getTypeReferenceSerializationKind(typeName, location) {
+            // ensure both `typeName` and `location` are parse tree nodes.
+            typeName = ts.getParseTreeNode(typeName, ts.isEntityName);
+            if (!typeName)
+                return ts.TypeReferenceSerializationKind.Unknown;
+            if (location) {
+                location = ts.getParseTreeNode(location);
+                if (!location)
+                    return ts.TypeReferenceSerializationKind.Unknown;
+            }
+            // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
+            var valueSymbol = resolveEntityName(typeName, 107455 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
+            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
+            var typeSymbol = resolveEntityName(typeName, 793064 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
+            if (valueSymbol && valueSymbol === typeSymbol) {
+                var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
+                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
+                    return ts.TypeReferenceSerializationKind.Promise;
+                }
+                var constructorType = getTypeOfSymbol(valueSymbol);
+                if (constructorType && isConstructorType(constructorType)) {
+                    return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
+                }
+            }
+            // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
+            if (!typeSymbol) {
+                return ts.TypeReferenceSerializationKind.ObjectType;
+            }
+            var type = getDeclaredTypeOfSymbol(typeSymbol);
+            if (type === unknownType) {
+                return ts.TypeReferenceSerializationKind.Unknown;
+            }
+            else if (type.flags & 1 /* Any */) {
+                return ts.TypeReferenceSerializationKind.ObjectType;
+            }
+            else if (isTypeAssignableToKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) {
+                return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType;
+            }
+            else if (isTypeAssignableToKind(type, 136 /* BooleanLike */)) {
+                return ts.TypeReferenceSerializationKind.BooleanType;
+            }
+            else if (isTypeAssignableToKind(type, 84 /* NumberLike */)) {
+                return ts.TypeReferenceSerializationKind.NumberLikeType;
+            }
+            else if (isTypeAssignableToKind(type, 262178 /* StringLike */)) {
+                return ts.TypeReferenceSerializationKind.StringLikeType;
+            }
+            else if (isTupleType(type)) {
+                return ts.TypeReferenceSerializationKind.ArrayLikeType;
+            }
+            else if (isTypeAssignableToKind(type, 512 /* ESSymbol */)) {
+                return ts.TypeReferenceSerializationKind.ESSymbolType;
+            }
+            else if (isFunctionType(type)) {
+                return ts.TypeReferenceSerializationKind.TypeWithCallSignature;
+            }
+            else if (isArrayType(type)) {
+                return ts.TypeReferenceSerializationKind.ArrayLikeType;
+            }
+            else {
+                return ts.TypeReferenceSerializationKind.ObjectType;
+            }
+        }
+        function writeTypeOfDeclaration(declaration, enclosingDeclaration, flags, writer) {
+            // Get type of the symbol if this is the valid symbol otherwise get type at location
+            var symbol = getSymbolOfNode(declaration);
+            var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */))
+                ? getWidenedLiteralType(getTypeOfSymbol(symbol))
+                : unknownType;
+            if (flags & 8192 /* AddUndefined */) {
+                type = getNullableType(type, 2048 /* Undefined */);
+            }
+            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
+        }
+        function writeReturnTypeOfSignatureDeclaration(signatureDeclaration, enclosingDeclaration, flags, writer) {
+            var signature = getSignatureFromDeclaration(signatureDeclaration);
+            getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags);
+        }
+        function writeTypeOfExpression(expr, enclosingDeclaration, flags, writer) {
+            var type = getWidenedType(getRegularTypeOfExpression(expr));
+            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
+        }
+        function hasGlobalName(name) {
+            return globals.has(ts.escapeLeadingUnderscores(name));
+        }
+        function getReferencedValueSymbol(reference, startInDeclarationContainer) {
+            var resolvedSymbol = getNodeLinks(reference).resolvedSymbol;
+            if (resolvedSymbol) {
+                return resolvedSymbol;
+            }
+            var location = reference;
+            if (startInDeclarationContainer) {
+                // When resolving the name of a declaration as a value, we need to start resolution
+                // at a point outside of the declaration.
+                var parent = reference.parent;
+                if (ts.isDeclaration(parent) && reference === parent.name) {
+                    location = getDeclarationContainer(parent);
+                }
+            }
+            return resolveName(location, reference.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
+        }
+        function getReferencedValueDeclaration(reference) {
+            if (!ts.isGeneratedIdentifier(reference)) {
+                reference = ts.getParseTreeNode(reference, ts.isIdentifier);
+                if (reference) {
+                    var symbol = getReferencedValueSymbol(reference);
+                    if (symbol) {
+                        return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
+                    }
+                }
+            }
+            return undefined;
+        }
+        function isLiteralConstDeclaration(node) {
+            if (ts.isConst(node)) {
+                var type = getTypeOfSymbol(getSymbolOfNode(node));
+                return !!(type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 1048576 /* FreshLiteral */);
+            }
+            return false;
+        }
+        function writeLiteralConstValue(node, writer) {
+            var type = getTypeOfSymbol(getSymbolOfNode(node));
+            writer.writeStringLiteral(literalTypeToString(type));
+        }
+        function createResolver() {
+            // this variable and functions that use it are deliberately moved here from the outer scope
+            // to avoid scope pollution
+            var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
+            var fileToDirective;
+            if (resolvedTypeReferenceDirectives) {
+                // populate reverse mapping: file path -> type reference directive that was resolved to this file
+                fileToDirective = ts.createMap();
+                resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) {
+                    if (!resolvedDirective) {
+                        return;
+                    }
+                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
+                    fileToDirective.set(file.path, key);
+                });
+            }
+            return {
+                getReferencedExportContainer: getReferencedExportContainer,
+                getReferencedImportDeclaration: getReferencedImportDeclaration,
+                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
+                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
+                isValueAliasDeclaration: function (node) {
+                    node = ts.getParseTreeNode(node);
+                    // Synthesized nodes are always treated like values.
+                    return node ? isValueAliasDeclaration(node) : true;
+                },
+                hasGlobalName: hasGlobalName,
+                isReferencedAliasDeclaration: function (node, checkChildren) {
+                    node = ts.getParseTreeNode(node);
+                    // Synthesized nodes are always treated as referenced.
+                    return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
+                },
+                getNodeCheckFlags: function (node) {
+                    node = ts.getParseTreeNode(node);
+                    return node ? getNodeCheckFlags(node) : undefined;
+                },
+                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
+                isDeclarationVisible: isDeclarationVisible,
+                isImplementationOfOverload: isImplementationOfOverload,
+                isRequiredInitializedParameter: isRequiredInitializedParameter,
+                isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty,
+                writeTypeOfDeclaration: writeTypeOfDeclaration,
+                writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration,
+                writeTypeOfExpression: writeTypeOfExpression,
+                isSymbolAccessible: isSymbolAccessible,
+                isEntityNameVisible: isEntityNameVisible,
+                getConstantValue: function (node) {
+                    node = ts.getParseTreeNode(node, canHaveConstantValue);
+                    return node ? getConstantValue(node) : undefined;
+                },
+                collectLinkedAliases: collectLinkedAliases,
+                getReferencedValueDeclaration: getReferencedValueDeclaration,
+                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
+                isOptionalParameter: isOptionalParameter,
+                moduleExportsSomeValue: moduleExportsSomeValue,
+                isArgumentsLocalBinding: isArgumentsLocalBinding,
+                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
+                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
+                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol,
+                isLiteralConstDeclaration: isLiteralConstDeclaration,
+                writeLiteralConstValue: writeLiteralConstValue,
+                getJsxFactoryEntity: function () { return _jsxFactoryEntity; }
+            };
+            // defined here to avoid outer scope pollution
+            function getTypeReferenceDirectivesForEntityName(node) {
+                // program does not have any files with type reference directives - bail out
+                if (!fileToDirective) {
+                    return undefined;
+                }
+                // property access can only be used as values
+                // qualified names can only be used as types\namespaces
+                // identifiers are treated as values only if they appear in type queries
+                var meaning = (node.kind === 179 /* PropertyAccessExpression */) || (node.kind === 71 /* Identifier */ && isInTypeQuery(node))
+                    ? 107455 /* Value */ | 1048576 /* ExportValue */
+                    : 793064 /* Type */ | 1920 /* Namespace */;
+                var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
+                return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
+            }
+            // defined here to avoid outer scope pollution
+            function getTypeReferenceDirectivesForSymbol(symbol, meaning) {
+                // program does not have any files with type reference directives - bail out
+                if (!fileToDirective) {
+                    return undefined;
+                }
+                if (!isSymbolFromTypeDeclarationFile(symbol)) {
+                    return undefined;
+                }
+                // check what declarations in the symbol can contribute to the target meaning
+                var typeReferenceDirectives;
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    // check meaning of the local symbol to see if declaration needs to be analyzed further
+                    if (decl.symbol && decl.symbol.flags & meaning) {
+                        var file = ts.getSourceFileOfNode(decl);
+                        var typeReferenceDirective = fileToDirective.get(file.path);
+                        if (typeReferenceDirective) {
+                            (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
+                        }
+                        else {
+                            // found at least one entry that does not originate from type reference directive
+                            return undefined;
+                        }
+                    }
+                }
+                return typeReferenceDirectives;
+            }
+            function isSymbolFromTypeDeclarationFile(symbol) {
+                // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
+                if (!symbol.declarations) {
+                    return false;
+                }
+                // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
+                // external modules cannot define or contribute to type declaration files
+                var current = symbol;
+                while (true) {
+                    var parent = getParentOfSymbol(current);
+                    if (parent) {
+                        current = parent;
+                    }
+                    else {
+                        break;
+                    }
+                }
+                if (current.valueDeclaration && current.valueDeclaration.kind === 265 /* SourceFile */ && current.flags & 512 /* ValueModule */) {
+                    return false;
+                }
+                // check that at least one declaration of top level symbol originates from type declaration file
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    var file = ts.getSourceFileOfNode(decl);
+                    if (fileToDirective.has(file.path)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+        function getExternalModuleFileFromDeclaration(declaration) {
+            var specifier = ts.getExternalModuleName(declaration);
+            var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined);
+            if (!moduleSymbol) {
+                return undefined;
+            }
+            return ts.getDeclarationOfKind(moduleSymbol, 265 /* SourceFile */);
+        }
+        function initializeTypeChecker() {
+            // Bind all source files and propagate errors
+            for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) {
+                var file = _a[_i];
+                ts.bindSourceFile(file, compilerOptions);
+            }
+            // Initialize global symbol table
+            var augmentations;
+            for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) {
+                var file = _c[_b];
+                if (!ts.isExternalOrCommonJsModule(file)) {
+                    mergeSymbolTable(globals, file.locals);
+                }
+                if (file.patternAmbientModules && file.patternAmbientModules.length) {
+                    patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules);
+                }
+                if (file.moduleAugmentations.length) {
+                    (augmentations || (augmentations = [])).push(file.moduleAugmentations);
+                }
+                if (file.symbol && file.symbol.globalExports) {
+                    // Merge in UMD exports with first-in-wins semantics (see #9771)
+                    var source = file.symbol.globalExports;
+                    source.forEach(function (sourceSymbol, id) {
+                        if (!globals.has(id)) {
+                            globals.set(id, sourceSymbol);
+                        }
+                    });
+                }
+            }
+            if (augmentations) {
+                // merge module augmentations.
+                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
+                for (var _d = 0, augmentations_1 = augmentations; _d < augmentations_1.length; _d++) {
+                    var list = augmentations_1[_d];
+                    for (var _e = 0, list_1 = list; _e < list_1.length; _e++) {
+                        var augmentation = list_1[_e];
+                        mergeModuleAugmentation(augmentation);
+                    }
+                }
+            }
+            // Setup global builtins
+            addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
+            getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
+            getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true);
+            getSymbolLinks(unknownSymbol).type = unknownType;
+            // Initialize special types
+            globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true);
+            globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true);
+            globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true);
+            globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true);
+            globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true);
+            globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true);
+            globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true);
+            anyArrayType = createArrayType(anyType);
+            autoArrayType = createArrayType(autoType);
+            globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1);
+            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
+            globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
+        }
+        function checkExternalEmitHelpers(location, helpers) {
+            if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
+                var sourceFile = ts.getSourceFileOfNode(location);
+                if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !ts.isInAmbientContext(location)) {
+                    var helpersModule = resolveHelpersModule(sourceFile, location);
+                    if (helpersModule !== unknownSymbol) {
+                        var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
+                        for (var helper = 1 /* FirstEmitHelper */; helper <= 65536 /* LastEmitHelper */; helper <<= 1) {
+                            if (uncheckedHelpers & helper) {
+                                var name = getHelperName(helper);
+                                var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 107455 /* Value */);
+                                if (!symbol) {
+                                    error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, ts.externalHelpersModuleNameText, name);
+                                }
+                            }
+                        }
+                    }
+                    requestedExternalEmitHelpers |= helpers;
+                }
+            }
+        }
+        function getHelperName(helper) {
+            switch (helper) {
+                case 1 /* Extends */: return "__extends";
+                case 2 /* Assign */: return "__assign";
+                case 4 /* Rest */: return "__rest";
+                case 8 /* Decorate */: return "__decorate";
+                case 16 /* Metadata */: return "__metadata";
+                case 32 /* Param */: return "__param";
+                case 64 /* Awaiter */: return "__awaiter";
+                case 128 /* Generator */: return "__generator";
+                case 256 /* Values */: return "__values";
+                case 512 /* Read */: return "__read";
+                case 1024 /* Spread */: return "__spread";
+                case 2048 /* Await */: return "__await";
+                case 4096 /* AsyncGenerator */: return "__asyncGenerator";
+                case 8192 /* AsyncDelegator */: return "__asyncDelegator";
+                case 16384 /* AsyncValues */: return "__asyncValues";
+                case 32768 /* ExportStar */: return "__exportStar";
+                case 65536 /* MakeTemplateObject */: return "__makeTemplateObject";
+                default: ts.Debug.fail("Unrecognized helper");
+            }
+        }
+        function resolveHelpersModule(node, errorNode) {
+            if (!externalHelpersModule) {
+                externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
+            }
+            return externalHelpersModule;
+        }
+        // GRAMMAR CHECKING
+        function checkGrammarDecorators(node) {
+            if (!node.decorators) {
+                return false;
+            }
+            if (!ts.nodeCanBeDecorated(node)) {
+                if (node.kind === 151 /* MethodDeclaration */ && !ts.nodeIsPresent(node.body)) {
+                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
+                }
+                else {
+                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here);
+                }
+            }
+            else if (node.kind === 153 /* GetAccessor */ || node.kind === 154 /* SetAccessor */) {
+                var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
+                if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) {
+                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
+                }
+            }
+            return false;
+        }
+        function checkGrammarModifiers(node) {
+            var quickResult = reportObviousModifierErrors(node);
+            if (quickResult !== undefined) {
+                return quickResult;
+            }
+            var lastStatic, lastDeclare, lastAsync, lastReadonly;
+            var flags = 0 /* None */;
+            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
+                var modifier = _a[_i];
+                if (modifier.kind !== 131 /* ReadonlyKeyword */) {
+                    if (node.kind === 148 /* PropertySignature */ || node.kind === 150 /* MethodSignature */) {
+                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
+                    }
+                    if (node.kind === 157 /* IndexSignature */) {
+                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
+                    }
+                }
+                switch (modifier.kind) {
+                    case 76 /* ConstKeyword */:
+                        if (node.kind !== 232 /* EnumDeclaration */ && node.parent.kind === 229 /* ClassDeclaration */) {
+                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(76 /* ConstKeyword */));
+                        }
+                        break;
+                    case 114 /* PublicKeyword */:
+                    case 113 /* ProtectedKeyword */:
+                    case 112 /* PrivateKeyword */:
+                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
+                        if (flags & 28 /* AccessibilityModifier */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
+                        }
+                        else if (flags & 32 /* Static */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
+                        }
+                        else if (flags & 64 /* Readonly */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
+                        }
+                        else if (flags & 256 /* Async */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
+                        }
+                        else if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
+                        }
+                        else if (flags & 128 /* Abstract */) {
+                            if (modifier.kind === 112 /* PrivateKeyword */) {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
+                            }
+                            else {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
+                            }
+                        }
+                        flags |= ts.modifierToFlag(modifier.kind);
+                        break;
+                    case 115 /* StaticKeyword */:
+                        if (flags & 32 /* Static */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
+                        }
+                        else if (flags & 64 /* Readonly */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
+                        }
+                        else if (flags & 256 /* Async */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
+                        }
+                        else if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
+                        }
+                        else if (node.kind === 146 /* Parameter */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
+                        }
+                        else if (flags & 128 /* Abstract */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
+                        }
+                        flags |= 32 /* Static */;
+                        lastStatic = modifier;
+                        break;
+                    case 131 /* ReadonlyKeyword */:
+                        if (flags & 64 /* Readonly */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
+                        }
+                        else if (node.kind !== 149 /* PropertyDeclaration */ && node.kind !== 148 /* PropertySignature */ && node.kind !== 157 /* IndexSignature */ && node.kind !== 146 /* Parameter */) {
+                            // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
+                            return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
+                        }
+                        flags |= 64 /* Readonly */;
+                        lastReadonly = modifier;
+                        break;
+                    case 84 /* ExportKeyword */:
+                        if (flags & 1 /* Export */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
+                        }
+                        else if (flags & 2 /* Ambient */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
+                        }
+                        else if (flags & 128 /* Abstract */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
+                        }
+                        else if (flags & 256 /* Async */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
+                        }
+                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
+                        }
+                        else if (node.kind === 146 /* Parameter */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
+                        }
+                        flags |= 1 /* Export */;
+                        break;
+                    case 79 /* DefaultKeyword */:
+                        var container = node.parent.kind === 265 /* SourceFile */ ? node.parent : node.parent.parent;
+                        if (container.kind === 233 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
+                        }
+                        flags |= 512 /* Default */;
+                        break;
+                    case 124 /* DeclareKeyword */:
+                        if (flags & 2 /* Ambient */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
+                        }
+                        else if (flags & 256 /* Async */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
+                        }
+                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
+                        }
+                        else if (node.kind === 146 /* Parameter */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
+                        }
+                        else if (ts.isInAmbientContext(node.parent) && node.parent.kind === 234 /* ModuleBlock */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
+                        }
+                        flags |= 2 /* Ambient */;
+                        lastDeclare = modifier;
+                        break;
+                    case 117 /* AbstractKeyword */:
+                        if (flags & 128 /* Abstract */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
+                        }
+                        if (node.kind !== 229 /* ClassDeclaration */) {
+                            if (node.kind !== 151 /* MethodDeclaration */ &&
+                                node.kind !== 149 /* PropertyDeclaration */ &&
+                                node.kind !== 153 /* GetAccessor */ &&
+                                node.kind !== 154 /* SetAccessor */) {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
+                            }
+                            if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
+                            }
+                            if (flags & 32 /* Static */) {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
+                            }
+                            if (flags & 8 /* Private */) {
+                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
+                            }
+                        }
+                        flags |= 128 /* Abstract */;
+                        break;
+                    case 120 /* AsyncKeyword */:
+                        if (flags & 256 /* Async */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async");
+                        }
+                        else if (flags & 2 /* Ambient */ || ts.isInAmbientContext(node.parent)) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
+                        }
+                        else if (node.kind === 146 /* Parameter */) {
+                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
+                        }
+                        flags |= 256 /* Async */;
+                        lastAsync = modifier;
+                        break;
+                }
+            }
+            if (node.kind === 152 /* Constructor */) {
+                if (flags & 32 /* Static */) {
+                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
+                }
+                if (flags & 128 /* Abstract */) {
+                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract");
+                }
+                else if (flags & 256 /* Async */) {
+                    return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
+                }
+                else if (flags & 64 /* Readonly */) {
+                    return grammarErrorOnNode(lastReadonly, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
+                }
+                return;
+            }
+            else if ((node.kind === 238 /* ImportDeclaration */ || node.kind === 237 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
+                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
+            }
+            else if (node.kind === 146 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && ts.isBindingPattern(node.name)) {
+                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
+            }
+            else if (node.kind === 146 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) {
+                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
+            }
+            if (flags & 256 /* Async */) {
+                return checkGrammarAsyncModifier(node, lastAsync);
+            }
+        }
+        /**
+         * true | false: Early return this value from checkGrammarModifiers.
+         * undefined: Need to do full checking on the modifiers.
+         */
+        function reportObviousModifierErrors(node) {
+            return !node.modifiers
+                ? false
+                : shouldReportBadModifier(node)
+                    ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here)
+                    : undefined;
+        }
+        function shouldReportBadModifier(node) {
+            switch (node.kind) {
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 152 /* Constructor */:
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 157 /* IndexSignature */:
+                case 233 /* ModuleDeclaration */:
+                case 238 /* ImportDeclaration */:
+                case 237 /* ImportEqualsDeclaration */:
+                case 244 /* ExportDeclaration */:
+                case 243 /* ExportAssignment */:
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                case 146 /* Parameter */:
+                    return false;
+                default:
+                    if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
+                        return false;
+                    }
+                    switch (node.kind) {
+                        case 228 /* FunctionDeclaration */:
+                            return nodeHasAnyModifiersExcept(node, 120 /* AsyncKeyword */);
+                        case 229 /* ClassDeclaration */:
+                            return nodeHasAnyModifiersExcept(node, 117 /* AbstractKeyword */);
+                        case 230 /* InterfaceDeclaration */:
+                        case 208 /* VariableStatement */:
+                        case 231 /* TypeAliasDeclaration */:
+                            return true;
+                        case 232 /* EnumDeclaration */:
+                            return nodeHasAnyModifiersExcept(node, 76 /* ConstKeyword */);
+                        default:
+                            ts.Debug.fail();
+                            return false;
+                    }
+            }
+        }
+        function nodeHasAnyModifiersExcept(node, allowedModifier) {
+            return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier;
+        }
+        function checkGrammarAsyncModifier(node, asyncModifier) {
+            switch (node.kind) {
+                case 151 /* MethodDeclaration */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    return false;
+            }
+            return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async");
+        }
+        function checkGrammarForDisallowedTrailingComma(list) {
+            if (list && list.hasTrailingComma) {
+                var start = list.end - ",".length;
+                var end = list.end;
+                return grammarErrorAtPos(list[0], start, end - start, ts.Diagnostics.Trailing_comma_not_allowed);
+            }
+        }
+        function checkGrammarTypeParameterList(typeParameters, file) {
+            if (checkGrammarForDisallowedTrailingComma(typeParameters)) {
+                return true;
+            }
+            if (typeParameters && typeParameters.length === 0) {
+                var start = typeParameters.pos - "<".length;
+                var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length;
+                return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
+            }
+        }
+        function checkGrammarParameterList(parameters) {
+            var seenOptionalParameter = false;
+            var parameterCount = parameters.length;
+            for (var i = 0; i < parameterCount; i++) {
+                var parameter = parameters[i];
+                if (parameter.dotDotDotToken) {
+                    if (i !== (parameterCount - 1)) {
+                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
+                    }
+                    if (ts.isBindingPattern(parameter.name)) {
+                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
+                    }
+                    if (parameter.questionToken) {
+                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
+                    }
+                    if (parameter.initializer) {
+                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
+                    }
+                }
+                else if (parameter.questionToken) {
+                    seenOptionalParameter = true;
+                    if (parameter.initializer) {
+                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
+                    }
+                }
+                else if (seenOptionalParameter && !parameter.initializer) {
+                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
+                }
+            }
+        }
+        function checkGrammarFunctionLikeDeclaration(node) {
+            // Prevent cascading error by short-circuit
+            var file = ts.getSourceFileOfNode(node);
+            return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
+                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
+        }
+        function checkGrammarClassLikeDeclaration(node) {
+            var file = ts.getSourceFileOfNode(node);
+            return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
+        }
+        function checkGrammarArrowFunction(node, file) {
+            if (node.kind === 187 /* ArrowFunction */) {
+                var arrowFunction = node;
+                var startLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.pos).line;
+                var endLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.end).line;
+                if (startLine !== endLine) {
+                    return grammarErrorOnNode(arrowFunction.equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow);
+                }
+            }
+            return false;
+        }
+        function checkGrammarIndexSignatureParameters(node) {
+            var parameter = node.parameters[0];
+            if (node.parameters.length !== 1) {
+                if (parameter) {
+                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
+                }
+                else {
+                    return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
+                }
+            }
+            if (parameter.dotDotDotToken) {
+                return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
+            }
+            if (ts.hasModifiers(parameter)) {
+                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
+            }
+            if (parameter.questionToken) {
+                return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
+            }
+            if (parameter.initializer) {
+                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
+            }
+            if (!parameter.type) {
+                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
+            }
+            if (parameter.type.kind !== 136 /* StringKeyword */ && parameter.type.kind !== 133 /* NumberKeyword */) {
+                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_or_number);
+            }
+            if (!node.type) {
+                return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
+            }
+        }
+        function checkGrammarIndexSignature(node) {
+            // Prevent cascading error by short-circuit
+            return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node);
+        }
+        function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
+            if (typeArguments && typeArguments.length === 0) {
+                var sourceFile = ts.getSourceFileOfNode(node);
+                var start = typeArguments.pos - "<".length;
+                var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
+                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
+            }
+        }
+        function checkGrammarTypeArguments(node, typeArguments) {
+            return checkGrammarForDisallowedTrailingComma(typeArguments) ||
+                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
+        }
+        function checkGrammarForOmittedArgument(args) {
+            if (args) {
+                for (var _i = 0, args_5 = args; _i < args_5.length; _i++) {
+                    var arg = args_5[_i];
+                    if (arg.kind === 200 /* OmittedExpression */) {
+                        return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
+                    }
+                }
+            }
+        }
+        function checkGrammarArguments(args) {
+            return checkGrammarForOmittedArgument(args);
+        }
+        function checkGrammarHeritageClause(node) {
+            var types = node.types;
+            if (checkGrammarForDisallowedTrailingComma(types)) {
+                return true;
+            }
+            if (types && types.length === 0) {
+                var listType = ts.tokenToString(node.token);
+                return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
+            }
+            return ts.forEach(types, checkGrammarExpressionWithTypeArguments);
+        }
+        function checkGrammarExpressionWithTypeArguments(node) {
+            return checkGrammarTypeArguments(node, node.typeArguments);
+        }
+        function checkGrammarClassDeclarationHeritageClauses(node) {
+            var seenExtendsClause = false;
+            var seenImplementsClause = false;
+            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && node.heritageClauses) {
+                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
+                    var heritageClause = _a[_i];
+                    if (heritageClause.token === 85 /* ExtendsKeyword */) {
+                        if (seenExtendsClause) {
+                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
+                        }
+                        if (seenImplementsClause) {
+                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause);
+                        }
+                        if (heritageClause.types.length > 1) {
+                            return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class);
+                        }
+                        seenExtendsClause = true;
+                    }
+                    else {
+                        ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */);
+                        if (seenImplementsClause) {
+                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen);
+                        }
+                        seenImplementsClause = true;
+                    }
+                    // Grammar checking heritageClause inside class declaration
+                    checkGrammarHeritageClause(heritageClause);
+                }
+            }
+        }
+        function checkGrammarInterfaceDeclaration(node) {
+            var seenExtendsClause = false;
+            if (node.heritageClauses) {
+                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
+                    var heritageClause = _a[_i];
+                    if (heritageClause.token === 85 /* ExtendsKeyword */) {
+                        if (seenExtendsClause) {
+                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
+                        }
+                        seenExtendsClause = true;
+                    }
+                    else {
+                        ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */);
+                        return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause);
+                    }
+                    // Grammar checking heritageClause inside class declaration
+                    checkGrammarHeritageClause(heritageClause);
+                }
+            }
+            return false;
+        }
+        function checkGrammarComputedPropertyName(node) {
+            // If node is not a computedPropertyName, just skip the grammar checking
+            if (node.kind !== 144 /* ComputedPropertyName */) {
+                return false;
+            }
+            var computedPropertyName = node;
+            if (computedPropertyName.expression.kind === 194 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 26 /* CommaToken */) {
+                return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
+            }
+        }
+        function checkGrammarForGenerator(node) {
+            if (node.asteriskToken) {
+                ts.Debug.assert(node.kind === 228 /* FunctionDeclaration */ ||
+                    node.kind === 186 /* FunctionExpression */ ||
+                    node.kind === 151 /* MethodDeclaration */);
+                if (ts.isInAmbientContext(node)) {
+                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
+                }
+                if (!node.body) {
+                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
+                }
+            }
+        }
+        function checkGrammarForInvalidQuestionMark(questionToken, message) {
+            if (questionToken) {
+                return grammarErrorOnNode(questionToken, message);
+            }
+        }
+        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
+            var seen = ts.createUnderscoreEscapedMap();
+            var Property = 1;
+            var GetAccessor = 2;
+            var SetAccessor = 4;
+            var GetOrSetAccessor = GetAccessor | SetAccessor;
+            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+                var prop = _a[_i];
+                if (prop.kind === 263 /* SpreadAssignment */) {
+                    continue;
+                }
+                var name = prop.name;
+                if (name.kind === 144 /* ComputedPropertyName */) {
+                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
+                    checkGrammarComputedPropertyName(name);
+                }
+                if (prop.kind === 262 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
+                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
+                    // outside of destructuring it is a syntax error
+                    return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
+                }
+                // Modifiers are never allowed on properties except for 'async' on a method declaration
+                if (prop.modifiers) {
+                    for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) {
+                        var mod = _c[_b];
+                        if (mod.kind !== 120 /* AsyncKeyword */ || prop.kind !== 151 /* MethodDeclaration */) {
+                            grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod));
+                        }
+                    }
+                }
+                // ECMA-262 11.1.5 Object Initializer
+                // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
+                // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
+                // IsDataDescriptor(propId.descriptor) is true.
+                //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
+                //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
+                //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
+                // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
+                var currentKind = void 0;
+                if (prop.kind === 261 /* PropertyAssignment */ || prop.kind === 262 /* ShorthandPropertyAssignment */) {
+                    // Grammar checking for computedPropertyName and shorthandPropertyAssignment
+                    checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
+                    if (name.kind === 8 /* NumericLiteral */) {
+                        checkGrammarNumericLiteral(name);
+                    }
+                    currentKind = Property;
+                }
+                else if (prop.kind === 151 /* MethodDeclaration */) {
+                    currentKind = Property;
+                }
+                else if (prop.kind === 153 /* GetAccessor */) {
+                    currentKind = GetAccessor;
+                }
+                else if (prop.kind === 154 /* SetAccessor */) {
+                    currentKind = SetAccessor;
+                }
+                else {
+                    ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
+                }
+                var effectiveName = ts.getPropertyNameForPropertyNameNode(name);
+                if (effectiveName === undefined) {
+                    continue;
+                }
+                var existingKind = seen.get(effectiveName);
+                if (!existingKind) {
+                    seen.set(effectiveName, currentKind);
+                }
+                else {
+                    if (currentKind === Property && existingKind === Property) {
+                        grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name));
+                    }
+                    else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
+                        if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
+                            seen.set(effectiveName, currentKind | existingKind);
+                        }
+                        else {
+                            return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
+                        }
+                    }
+                    else {
+                        return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
+                    }
+                }
+            }
+        }
+        function checkGrammarJsxElement(node) {
+            var seen = ts.createUnderscoreEscapedMap();
+            for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) {
+                var attr = _a[_i];
+                if (attr.kind === 255 /* JsxSpreadAttribute */) {
+                    continue;
+                }
+                var jsxAttr = attr;
+                var name = jsxAttr.name;
+                if (!seen.get(name.escapedText)) {
+                    seen.set(name.escapedText, true);
+                }
+                else {
+                    return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
+                }
+                var initializer = jsxAttr.initializer;
+                if (initializer && initializer.kind === 256 /* JsxExpression */ && !initializer.expression) {
+                    return grammarErrorOnNode(jsxAttr.initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
+                }
+            }
+        }
+        function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
+            if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
+                return true;
+            }
+            if (forInOrOfStatement.kind === 216 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
+                if ((forInOrOfStatement.flags & 16384 /* AwaitContext */) === 0 /* None */) {
+                    return grammarErrorOnNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
+                }
+            }
+            if (forInOrOfStatement.initializer.kind === 227 /* VariableDeclarationList */) {
+                var variableList = forInOrOfStatement.initializer;
+                if (!checkGrammarVariableDeclarationList(variableList)) {
+                    var declarations = variableList.declarations;
+                    // declarations.length can be zero if there is an error in variable declaration in for-of or for-in
+                    // See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
+                    // For example:
+                    //      var let = 10;
+                    //      for (let of [1,2,3]) {} // this is invalid ES6 syntax
+                    //      for (let in [1,2,3]) {} // this is invalid ES6 syntax
+                    // We will then want to skip on grammar checking on variableList declaration
+                    if (!declarations.length) {
+                        return false;
+                    }
+                    if (declarations.length > 1) {
+                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
+                            ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
+                            : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
+                        return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
+                    }
+                    var firstDeclaration = declarations[0];
+                    if (firstDeclaration.initializer) {
+                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
+                            ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
+                            : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
+                        return grammarErrorOnNode(firstDeclaration.name, diagnostic);
+                    }
+                    if (firstDeclaration.type) {
+                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
+                            ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
+                            : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
+                        return grammarErrorOnNode(firstDeclaration, diagnostic);
+                    }
+                }
+            }
+            return false;
+        }
+        function checkGrammarAccessor(accessor) {
+            var kind = accessor.kind;
+            if (languageVersion < 1 /* ES5 */) {
+                return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
+            }
+            else if (ts.isInAmbientContext(accessor)) {
+                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
+            }
+            else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) {
+                return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
+            }
+            else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) {
+                return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
+            }
+            else if (accessor.typeParameters) {
+                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
+            }
+            else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
+                return grammarErrorOnNode(accessor.name, kind === 153 /* GetAccessor */ ?
+                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
+                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
+            }
+            else if (kind === 154 /* SetAccessor */) {
+                if (accessor.type) {
+                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
+                }
+                else {
+                    var parameter = accessor.parameters[0];
+                    if (parameter.dotDotDotToken) {
+                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
+                    }
+                    else if (parameter.questionToken) {
+                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
+                    }
+                    else if (parameter.initializer) {
+                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
+                    }
+                }
+            }
+        }
+        /** Does the accessor have the right number of parameters?
+         * A get accessor has no parameters or a single `this` parameter.
+         * A set accessor has one parameter or a `this` parameter and one more parameter.
+         */
+        function doesAccessorHaveCorrectParameterCount(accessor) {
+            return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 153 /* GetAccessor */ ? 0 : 1);
+        }
+        function getAccessorThisParameter(accessor) {
+            if (accessor.parameters.length === (accessor.kind === 153 /* GetAccessor */ ? 1 : 2)) {
+                return ts.getThisParameter(accessor);
+            }
+        }
+        function checkGrammarForNonSymbolComputedProperty(node, message) {
+            if (ts.isDynamicName(node)) {
+                return grammarErrorOnNode(node, message);
+            }
+        }
+        function checkGrammarMethod(node) {
+            if (checkGrammarDisallowedModifiersOnObjectLiteralExpressionMethod(node) ||
+                checkGrammarFunctionLikeDeclaration(node) ||
+                checkGrammarForGenerator(node)) {
+                return true;
+            }
+            if (node.parent.kind === 178 /* ObjectLiteralExpression */) {
+                if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
+                    return true;
+                }
+                else if (node.body === undefined) {
+                    return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
+                }
+            }
+            if (ts.isClassLike(node.parent)) {
+                // Technically, computed properties in ambient contexts is disallowed
+                // for property declarations and accessors too, not just methods.
+                // However, property declarations disallow computed names in general,
+                // and accessors are not allowed in ambient contexts in general,
+                // so this error only really matters for methods.
+                if (ts.isInAmbientContext(node)) {
+                    return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol);
+                }
+                else if (!node.body) {
+                    return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol);
+                }
+            }
+            else if (node.parent.kind === 230 /* InterfaceDeclaration */) {
+                return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol);
+            }
+            else if (node.parent.kind === 163 /* TypeLiteral */) {
+                return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol);
+            }
+        }
+        function checkGrammarBreakOrContinueStatement(node) {
+            var current = node;
+            while (current) {
+                if (ts.isFunctionLike(current)) {
+                    return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
+                }
+                switch (current.kind) {
+                    case 222 /* LabeledStatement */:
+                        if (node.label && current.label.escapedText === node.label.escapedText) {
+                            // found matching label - verify that label usage is correct
+                            // continue can only target labels that are on iteration statements
+                            var isMisplacedContinueLabel = node.kind === 217 /* ContinueStatement */
+                                && !ts.isIterationStatement(current.statement, /*lookInLabeledStatement*/ true);
+                            if (isMisplacedContinueLabel) {
+                                return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
+                            }
+                            return false;
+                        }
+                        break;
+                    case 221 /* SwitchStatement */:
+                        if (node.kind === 218 /* BreakStatement */ && !node.label) {
+                            // unlabeled break within switch statement - ok
+                            return false;
+                        }
+                        break;
+                    default:
+                        if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) {
+                            // unlabeled break or continue within iteration statement - ok
+                            return false;
+                        }
+                        break;
+                }
+                current = current.parent;
+            }
+            if (node.label) {
+                var message = node.kind === 218 /* BreakStatement */
+                    ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement
+                    : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
+                return grammarErrorOnNode(node, message);
+            }
+            else {
+                var message = node.kind === 218 /* BreakStatement */
+                    ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement
+                    : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
+                return grammarErrorOnNode(node, message);
+            }
+        }
+        function checkGrammarBindingElement(node) {
+            if (node.dotDotDotToken) {
+                var elements = node.parent.elements;
+                if (node !== ts.lastOrUndefined(elements)) {
+                    return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
+                }
+                if (node.name.kind === 175 /* ArrayBindingPattern */ || node.name.kind === 174 /* ObjectBindingPattern */) {
+                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
+                }
+                if (node.initializer) {
+                    // Error on equals token which immediately precedes the initializer
+                    return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
+                }
+            }
+        }
+        function isStringOrNumberLiteralExpression(expr) {
+            return expr.kind === 9 /* StringLiteral */ || expr.kind === 8 /* NumericLiteral */ ||
+                expr.kind === 192 /* PrefixUnaryExpression */ && expr.operator === 38 /* MinusToken */ &&
+                    expr.operand.kind === 8 /* NumericLiteral */;
+        }
+        function checkGrammarVariableDeclaration(node) {
+            if (node.parent.parent.kind !== 215 /* ForInStatement */ && node.parent.parent.kind !== 216 /* ForOfStatement */) {
+                if (ts.isInAmbientContext(node)) {
+                    if (node.initializer) {
+                        if (ts.isConst(node) && !node.type) {
+                            if (!isStringOrNumberLiteralExpression(node.initializer)) {
+                                return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
+                            }
+                        }
+                        else {
+                            // Error on equals token which immediate precedes the initializer
+                            var equalsTokenLength = "=".length;
+                            return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
+                        }
+                    }
+                    if (node.initializer && !(ts.isConst(node) && isStringOrNumberLiteralExpression(node.initializer))) {
+                        // Error on equals token which immediate precedes the initializer
+                        var equalsTokenLength = "=".length;
+                        return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
+                    }
+                }
+                else if (!node.initializer) {
+                    if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) {
+                        return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer);
+                    }
+                    if (ts.isConst(node)) {
+                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
+                    }
+                }
+            }
+            if (compilerOptions.module !== ts.ModuleKind.ES2015 && compilerOptions.module !== ts.ModuleKind.ESNext && compilerOptions.module !== ts.ModuleKind.System && !compilerOptions.noEmit &&
+                !ts.isInAmbientContext(node.parent.parent) && ts.hasModifier(node.parent.parent, 1 /* Export */)) {
+                checkESModuleMarker(node.name);
+            }
+            var checkLetConstNames = (ts.isLet(node) || ts.isConst(node));
+            // 1. LexicalDeclaration : LetOrConst BindingList ;
+            // It is a Syntax Error if the BoundNames of BindingList contains "let".
+            // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
+            // It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
+            // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
+            // and its Identifier is eval or arguments
+            return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
+        }
+        function checkESModuleMarker(name) {
+            if (name.kind === 71 /* Identifier */) {
+                if (ts.idText(name) === "__esModule") {
+                    return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
+                }
+            }
+            else {
+                var elements = name.elements;
+                for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
+                    var element = elements_1[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        return checkESModuleMarker(element.name);
+                    }
+                }
+            }
+        }
+        function checkGrammarNameInLetOrConstDeclarations(name) {
+            if (name.kind === 71 /* Identifier */) {
+                if (name.originalKeywordKind === 110 /* LetKeyword */) {
+                    return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
+                }
+            }
+            else {
+                var elements = name.elements;
+                for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
+                    var element = elements_2[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        checkGrammarNameInLetOrConstDeclarations(element.name);
+                    }
+                }
+            }
+        }
+        function checkGrammarVariableDeclarationList(declarationList) {
+            var declarations = declarationList.declarations;
+            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
+                return true;
+            }
+            if (!declarationList.declarations.length) {
+                return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
+            }
+        }
+        function allowLetAndConstDeclarations(parent) {
+            switch (parent.kind) {
+                case 211 /* IfStatement */:
+                case 212 /* DoStatement */:
+                case 213 /* WhileStatement */:
+                case 220 /* WithStatement */:
+                case 214 /* ForStatement */:
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                    return false;
+                case 222 /* LabeledStatement */:
+                    return allowLetAndConstDeclarations(parent.parent);
+            }
+            return true;
+        }
+        function checkGrammarForDisallowedLetOrConstStatement(node) {
+            if (!allowLetAndConstDeclarations(node.parent)) {
+                if (ts.isLet(node.declarationList)) {
+                    return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
+                }
+                else if (ts.isConst(node.declarationList)) {
+                    return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
+                }
+            }
+        }
+        function checkGrammarMetaProperty(node) {
+            if (node.keywordToken === 94 /* NewKeyword */) {
+                if (node.name.escapedText !== "target") {
+                    return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target");
+                }
+            }
+        }
+        function hasParseDiagnostics(sourceFile) {
+            return sourceFile.parseDiagnostics.length > 0;
+        }
+        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
+            var sourceFile = ts.getSourceFileOfNode(node);
+            if (!hasParseDiagnostics(sourceFile)) {
+                var span_4 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
+                diagnostics.add(ts.createFileDiagnostic(sourceFile, span_4.start, span_4.length, message, arg0, arg1, arg2));
+                return true;
+            }
+        }
+        function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) {
+            var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile);
+            if (!hasParseDiagnostics(sourceFile)) {
+                diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
+                return true;
+            }
+        }
+        function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
+            var sourceFile = ts.getSourceFileOfNode(node);
+            if (!hasParseDiagnostics(sourceFile)) {
+                diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2));
+                return true;
+            }
+        }
+        function checkGrammarConstructorTypeParameters(node) {
+            if (node.typeParameters) {
+                return grammarErrorAtPos(node, node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
+            }
+        }
+        function checkGrammarConstructorTypeAnnotation(node) {
+            if (node.type) {
+                return grammarErrorOnNode(node.type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
+            }
+        }
+        function checkGrammarProperty(node) {
+            if (ts.isClassLike(node.parent)) {
+                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
+                    return true;
+                }
+            }
+            else if (node.parent.kind === 230 /* InterfaceDeclaration */) {
+                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol)) {
+                    return true;
+                }
+                if (node.initializer) {
+                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer);
+                }
+            }
+            else if (node.parent.kind === 163 /* TypeLiteral */) {
+                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol)) {
+                    return true;
+                }
+                if (node.initializer) {
+                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer);
+                }
+            }
+            if (ts.isInAmbientContext(node) && node.initializer) {
+                return grammarErrorOnFirstToken(node.initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
+            }
+        }
+        function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
+            // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
+            // interfaces and imports categories:
+            //
+            //  DeclarationElement:
+            //     ExportAssignment
+            //     export_opt   InterfaceDeclaration
+            //     export_opt   TypeAliasDeclaration
+            //     export_opt   ImportDeclaration
+            //     export_opt   ExternalImportDeclaration
+            //     export_opt   AmbientDeclaration
+            //
+            // TODO: The spec needs to be amended to reflect this grammar.
+            if (node.kind === 230 /* InterfaceDeclaration */ ||
+                node.kind === 231 /* TypeAliasDeclaration */ ||
+                node.kind === 238 /* ImportDeclaration */ ||
+                node.kind === 237 /* ImportEqualsDeclaration */ ||
+                node.kind === 244 /* ExportDeclaration */ ||
+                node.kind === 243 /* ExportAssignment */ ||
+                node.kind === 236 /* NamespaceExportDeclaration */ ||
+                ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) {
+                return false;
+            }
+            return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file);
+        }
+        function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
+            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
+                var decl = _a[_i];
+                if (ts.isDeclaration(decl) || decl.kind === 208 /* VariableStatement */) {
+                    if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        function checkGrammarSourceFile(node) {
+            return ts.isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
+        }
+        function checkGrammarStatementInAmbientContext(node) {
+            if (ts.isInAmbientContext(node)) {
+                // An accessors is already reported about the ambient context
+                if (ts.isAccessor(node.parent)) {
+                    return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
+                }
+                // Find containing block which is either Block, ModuleBlock, SourceFile
+                var links = getNodeLinks(node);
+                if (!links.hasReportedStatementInAmbientContext && ts.isFunctionLike(node.parent)) {
+                    return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
+                }
+                // We are either parented by another statement, or some sort of block.
+                // If we're in a block, we only want to really report an error once
+                // to prevent noisiness.  So use a bit on the block to indicate if
+                // this has already been reported, and don't report if it has.
+                //
+                if (node.parent.kind === 207 /* Block */ || node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
+                    var links_1 = getNodeLinks(node.parent);
+                    // Check if the containing block ever report this error
+                    if (!links_1.hasReportedStatementInAmbientContext) {
+                        return links_1.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
+                    }
+                }
+                else {
+                    // We must be parented by a statement.  If so, there's no need
+                    // to report the error as our parent will have already done it.
+                    // Debug.assert(isStatement(node.parent));
+                }
+            }
+        }
+        function checkGrammarNumericLiteral(node) {
+            // Grammar checking
+            if (node.numericLiteralFlags & 4 /* Octal */) {
+                var diagnosticMessage = void 0;
+                if (languageVersion >= 1 /* ES5 */) {
+                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
+                }
+                else if (ts.isChildOfNodeWithKind(node, 173 /* LiteralType */)) {
+                    diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
+                }
+                else if (ts.isChildOfNodeWithKind(node, 264 /* EnumMember */)) {
+                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
+                }
+                if (diagnosticMessage) {
+                    var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 38 /* MinusToken */;
+                    var literal = (withMinus ? "-" : "") + "0o" + node.text;
+                    return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
+                }
+            }
+        }
+        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
+            var sourceFile = ts.getSourceFileOfNode(node);
+            if (!hasParseDiagnostics(sourceFile)) {
+                var span_5 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
+                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span_5), /*length*/ 0, message, arg0, arg1, arg2));
+                return true;
+            }
+        }
+        function getAmbientModules() {
+            if (!ambientModulesCache) {
+                ambientModulesCache = [];
+                globals.forEach(function (global, sym) {
+                    // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
+                    if (ambientModuleSymbolRegex.test(sym)) {
+                        ambientModulesCache.push(global);
+                    }
+                });
+            }
+            return ambientModulesCache;
+        }
+        function checkGrammarImportCallExpression(node) {
+            if (modulekind === ts.ModuleKind.ES2015) {
+                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
+            }
+            if (node.typeArguments) {
+                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments);
+            }
+            var nodeArguments = node.arguments;
+            if (nodeArguments.length !== 1) {
+                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
+            }
+            // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
+            // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
+            if (ts.isSpreadElement(nodeArguments[0])) {
+                return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
+            }
+        }
+    }
+    ts.createTypeChecker = createTypeChecker;
+    /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
+    function isDeclarationNameOrImportPropertyName(name) {
+        switch (name.parent.kind) {
+            case 242 /* ImportSpecifier */:
+            case 246 /* ExportSpecifier */:
+                return true;
+            default:
+                return ts.isDeclarationName(name);
+        }
+    }
+    function isSomeImportDeclaration(decl) {
+        switch (decl.kind) {
+            case 239 /* ImportClause */: // For default import
+            case 237 /* ImportEqualsDeclaration */:
+            case 240 /* NamespaceImport */:
+            case 242 /* ImportSpecifier */:// For rename import `x as y`
+                return true;
+            case 71 /* Identifier */:
+                // For regular import, `decl` is an Identifier under the ImportSpecifier.
+                return decl.parent.kind === 242 /* ImportSpecifier */;
+            default:
+                return false;
+        }
+    }
+})(ts || (ts = {}));
+/// <reference path="core.ts"/>
+/// <reference path="utilities.ts"/>
+var ts;
+(function (ts) {
+    function createSynthesizedNode(kind) {
+        var node = ts.createNode(kind, -1, -1);
+        node.flags |= 8 /* Synthesized */;
+        return node;
+    }
+    /* @internal */
+    function updateNode(updated, original) {
+        if (updated !== original) {
+            setOriginalNode(updated, original);
+            setTextRange(updated, original);
+            if (original.startsOnNewLine) {
+                updated.startsOnNewLine = true;
+            }
+            ts.aggregateTransformFlags(updated);
+        }
+        return updated;
+    }
+    ts.updateNode = updateNode;
+    /**
+     * Make `elements` into a `NodeArray<T>`. If `elements` is `undefined`, returns an empty `NodeArray<T>`.
+     */
+    function createNodeArray(elements, hasTrailingComma) {
+        if (elements) {
+            if (ts.isNodeArray(elements)) {
+                return elements;
+            }
+        }
+        else {
+            elements = [];
+        }
+        var array = elements;
+        array.pos = -1;
+        array.end = -1;
+        array.hasTrailingComma = hasTrailingComma;
+        return array;
+    }
+    ts.createNodeArray = createNodeArray;
+    /**
+     * Creates a shallow, memberwise clone of a node with no source map location.
+     */
+    /* @internal */
+    function getSynthesizedClone(node) {
+        // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
+        // the original node. We also need to exclude specific properties and only include own-
+        // properties (to skip members already defined on the shared prototype).
+        if (node === undefined) {
+            return undefined;
+        }
+        var clone = createSynthesizedNode(node.kind);
+        clone.flags |= node.flags;
+        setOriginalNode(clone, node);
+        for (var key in node) {
+            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
+                continue;
+            }
+            clone[key] = node[key];
+        }
+        return clone;
+    }
+    ts.getSynthesizedClone = getSynthesizedClone;
+    function createLiteral(value) {
+        if (typeof value === "number") {
+            return createNumericLiteral(value + "");
+        }
+        if (typeof value === "boolean") {
+            return value ? createTrue() : createFalse();
+        }
+        if (ts.isString(value)) {
+            return createStringLiteral(value);
+        }
+        return createLiteralFromNode(value);
+    }
+    ts.createLiteral = createLiteral;
+    function createNumericLiteral(value) {
+        var node = createSynthesizedNode(8 /* NumericLiteral */);
+        node.text = value;
+        node.numericLiteralFlags = 0;
+        return node;
+    }
+    ts.createNumericLiteral = createNumericLiteral;
+    function createStringLiteral(text) {
+        var node = createSynthesizedNode(9 /* StringLiteral */);
+        node.text = text;
+        return node;
+    }
+    function createLiteralFromNode(sourceNode) {
+        var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode));
+        node.textSourceNode = sourceNode;
+        return node;
+    }
+    function createIdentifier(text, typeArguments) {
+        var node = createSynthesizedNode(71 /* Identifier */);
+        node.escapedText = ts.escapeLeadingUnderscores(text);
+        node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */;
+        node.autoGenerateKind = 0 /* None */;
+        node.autoGenerateId = 0;
+        if (typeArguments) {
+            node.typeArguments = createNodeArray(typeArguments);
+        }
+        return node;
+    }
+    ts.createIdentifier = createIdentifier;
+    function updateIdentifier(node, typeArguments) {
+        return node.typeArguments !== typeArguments
+            ? updateNode(createIdentifier(ts.idText(node), typeArguments), node)
+            : node;
+    }
+    ts.updateIdentifier = updateIdentifier;
+    var nextAutoGenerateId = 0;
+    /** Create a unique temporary variable. */
+    function createTempVariable(recordTempVariable) {
+        var name = createIdentifier("");
+        name.autoGenerateKind = 1 /* Auto */;
+        name.autoGenerateId = nextAutoGenerateId;
+        nextAutoGenerateId++;
+        if (recordTempVariable) {
+            recordTempVariable(name);
+        }
+        return name;
+    }
+    ts.createTempVariable = createTempVariable;
+    /** Create a unique temporary variable for use in a loop. */
+    function createLoopVariable() {
+        var name = createIdentifier("");
+        name.autoGenerateKind = 2 /* Loop */;
+        name.autoGenerateId = nextAutoGenerateId;
+        nextAutoGenerateId++;
+        return name;
+    }
+    ts.createLoopVariable = createLoopVariable;
+    /** Create a unique name based on the supplied text. */
+    function createUniqueName(text) {
+        var name = createIdentifier(text);
+        name.autoGenerateKind = 3 /* Unique */;
+        name.autoGenerateId = nextAutoGenerateId;
+        nextAutoGenerateId++;
+        return name;
+    }
+    ts.createUniqueName = createUniqueName;
+    /** Create a unique name generated for a node. */
+    function getGeneratedNameForNode(node) {
+        var name = createIdentifier("");
+        name.autoGenerateKind = 4 /* Node */;
+        name.autoGenerateId = nextAutoGenerateId;
+        name.original = node;
+        nextAutoGenerateId++;
+        return name;
+    }
+    ts.getGeneratedNameForNode = getGeneratedNameForNode;
+    // Punctuation
+    function createToken(token) {
+        return createSynthesizedNode(token);
+    }
+    ts.createToken = createToken;
+    // Reserved words
+    function createSuper() {
+        return createSynthesizedNode(97 /* SuperKeyword */);
+    }
+    ts.createSuper = createSuper;
+    function createThis() {
+        return createSynthesizedNode(99 /* ThisKeyword */);
+    }
+    ts.createThis = createThis;
+    function createNull() {
+        return createSynthesizedNode(95 /* NullKeyword */);
+    }
+    ts.createNull = createNull;
+    function createTrue() {
+        return createSynthesizedNode(101 /* TrueKeyword */);
+    }
+    ts.createTrue = createTrue;
+    function createFalse() {
+        return createSynthesizedNode(86 /* FalseKeyword */);
+    }
+    ts.createFalse = createFalse;
+    // Names
+    function createQualifiedName(left, right) {
+        var node = createSynthesizedNode(143 /* QualifiedName */);
+        node.left = left;
+        node.right = asName(right);
+        return node;
+    }
+    ts.createQualifiedName = createQualifiedName;
+    function updateQualifiedName(node, left, right) {
+        return node.left !== left
+            || node.right !== right
+            ? updateNode(createQualifiedName(left, right), node)
+            : node;
+    }
+    ts.updateQualifiedName = updateQualifiedName;
+    function createComputedPropertyName(expression) {
+        var node = createSynthesizedNode(144 /* ComputedPropertyName */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createComputedPropertyName = createComputedPropertyName;
+    function updateComputedPropertyName(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createComputedPropertyName(expression), node)
+            : node;
+    }
+    ts.updateComputedPropertyName = updateComputedPropertyName;
+    // Signature elements
+    function createTypeParameterDeclaration(name, constraint, defaultType) {
+        var node = createSynthesizedNode(145 /* TypeParameter */);
+        node.name = asName(name);
+        node.constraint = constraint;
+        node.default = defaultType;
+        return node;
+    }
+    ts.createTypeParameterDeclaration = createTypeParameterDeclaration;
+    function updateTypeParameterDeclaration(node, name, constraint, defaultType) {
+        return node.name !== name
+            || node.constraint !== constraint
+            || node.default !== defaultType
+            ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
+            : node;
+    }
+    ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration;
+    function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
+        var node = createSynthesizedNode(146 /* Parameter */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.dotDotDotToken = dotDotDotToken;
+        node.name = asName(name);
+        node.questionToken = questionToken;
+        node.type = type;
+        node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined;
+        return node;
+    }
+    ts.createParameter = createParameter;
+    function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.dotDotDotToken !== dotDotDotToken
+            || node.name !== name
+            || node.questionToken !== questionToken
+            || node.type !== type
+            || node.initializer !== initializer
+            ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
+            : node;
+    }
+    ts.updateParameter = updateParameter;
+    function createDecorator(expression) {
+        var node = createSynthesizedNode(147 /* Decorator */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        return node;
+    }
+    ts.createDecorator = createDecorator;
+    function updateDecorator(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createDecorator(expression), node)
+            : node;
+    }
+    ts.updateDecorator = updateDecorator;
+    // Type Elements
+    function createPropertySignature(modifiers, name, questionToken, type, initializer) {
+        var node = createSynthesizedNode(148 /* PropertySignature */);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.questionToken = questionToken;
+        node.type = type;
+        node.initializer = initializer;
+        return node;
+    }
+    ts.createPropertySignature = createPropertySignature;
+    function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) {
+        return node.modifiers !== modifiers
+            || node.name !== name
+            || node.questionToken !== questionToken
+            || node.type !== type
+            || node.initializer !== initializer
+            ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
+            : node;
+    }
+    ts.updatePropertySignature = updatePropertySignature;
+    function createProperty(decorators, modifiers, name, questionToken, type, initializer) {
+        var node = createSynthesizedNode(149 /* PropertyDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.questionToken = questionToken;
+        node.type = type;
+        node.initializer = initializer;
+        return node;
+    }
+    ts.createProperty = createProperty;
+    function updateProperty(node, decorators, modifiers, name, questionToken, type, initializer) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.questionToken !== questionToken
+            || node.type !== type
+            || node.initializer !== initializer
+            ? updateNode(createProperty(decorators, modifiers, name, questionToken, type, initializer), node)
+            : node;
+    }
+    ts.updateProperty = updateProperty;
+    function createMethodSignature(typeParameters, parameters, type, name, questionToken) {
+        var node = createSignatureDeclaration(150 /* MethodSignature */, typeParameters, parameters, type);
+        node.name = asName(name);
+        node.questionToken = questionToken;
+        return node;
+    }
+    ts.createMethodSignature = createMethodSignature;
+    function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) {
+        return node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.name !== name
+            || node.questionToken !== questionToken
+            ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
+            : node;
+    }
+    ts.updateMethodSignature = updateMethodSignature;
+    function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
+        var node = createSynthesizedNode(151 /* MethodDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.asteriskToken = asteriskToken;
+        node.name = asName(name);
+        node.questionToken = questionToken;
+        node.typeParameters = asNodeArray(typeParameters);
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        node.body = body;
+        return node;
+    }
+    ts.createMethod = createMethod;
+    function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.asteriskToken !== asteriskToken
+            || node.name !== name
+            || node.questionToken !== questionToken
+            || node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.body !== body
+            ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
+            : node;
+    }
+    ts.updateMethod = updateMethod;
+    function createConstructor(decorators, modifiers, parameters, body) {
+        var node = createSynthesizedNode(152 /* Constructor */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.typeParameters = undefined;
+        node.parameters = createNodeArray(parameters);
+        node.type = undefined;
+        node.body = body;
+        return node;
+    }
+    ts.createConstructor = createConstructor;
+    function updateConstructor(node, decorators, modifiers, parameters, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.parameters !== parameters
+            || node.body !== body
+            ? updateNode(createConstructor(decorators, modifiers, parameters, body), node)
+            : node;
+    }
+    ts.updateConstructor = updateConstructor;
+    function createGetAccessor(decorators, modifiers, name, parameters, type, body) {
+        var node = createSynthesizedNode(153 /* GetAccessor */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = undefined;
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        node.body = body;
+        return node;
+    }
+    ts.createGetAccessor = createGetAccessor;
+    function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.body !== body
+            ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node)
+            : node;
+    }
+    ts.updateGetAccessor = updateGetAccessor;
+    function createSetAccessor(decorators, modifiers, name, parameters, body) {
+        var node = createSynthesizedNode(154 /* SetAccessor */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = undefined;
+        node.parameters = createNodeArray(parameters);
+        node.body = body;
+        return node;
+    }
+    ts.createSetAccessor = createSetAccessor;
+    function updateSetAccessor(node, decorators, modifiers, name, parameters, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.parameters !== parameters
+            || node.body !== body
+            ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node)
+            : node;
+    }
+    ts.updateSetAccessor = updateSetAccessor;
+    function createCallSignature(typeParameters, parameters, type) {
+        return createSignatureDeclaration(155 /* CallSignature */, typeParameters, parameters, type);
+    }
+    ts.createCallSignature = createCallSignature;
+    function updateCallSignature(node, typeParameters, parameters, type) {
+        return updateSignatureDeclaration(node, typeParameters, parameters, type);
+    }
+    ts.updateCallSignature = updateCallSignature;
+    function createConstructSignature(typeParameters, parameters, type) {
+        return createSignatureDeclaration(156 /* ConstructSignature */, typeParameters, parameters, type);
+    }
+    ts.createConstructSignature = createConstructSignature;
+    function updateConstructSignature(node, typeParameters, parameters, type) {
+        return updateSignatureDeclaration(node, typeParameters, parameters, type);
+    }
+    ts.updateConstructSignature = updateConstructSignature;
+    function createIndexSignature(decorators, modifiers, parameters, type) {
+        var node = createSynthesizedNode(157 /* IndexSignature */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        return node;
+    }
+    ts.createIndexSignature = createIndexSignature;
+    function updateIndexSignature(node, decorators, modifiers, parameters, type) {
+        return node.parameters !== parameters
+            || node.type !== type
+            || node.decorators !== decorators
+            || node.modifiers !== modifiers
+            ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node)
+            : node;
+    }
+    ts.updateIndexSignature = updateIndexSignature;
+    /* @internal */
+    function createSignatureDeclaration(kind, typeParameters, parameters, type) {
+        var node = createSynthesizedNode(kind);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.parameters = asNodeArray(parameters);
+        node.type = type;
+        return node;
+    }
+    ts.createSignatureDeclaration = createSignatureDeclaration;
+    function updateSignatureDeclaration(node, typeParameters, parameters, type) {
+        return node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
+            : node;
+    }
+    // Types
+    function createKeywordTypeNode(kind) {
+        return createSynthesizedNode(kind);
+    }
+    ts.createKeywordTypeNode = createKeywordTypeNode;
+    function createTypePredicateNode(parameterName, type) {
+        var node = createSynthesizedNode(158 /* TypePredicate */);
+        node.parameterName = asName(parameterName);
+        node.type = type;
+        return node;
+    }
+    ts.createTypePredicateNode = createTypePredicateNode;
+    function updateTypePredicateNode(node, parameterName, type) {
+        return node.parameterName !== parameterName
+            || node.type !== type
+            ? updateNode(createTypePredicateNode(parameterName, type), node)
+            : node;
+    }
+    ts.updateTypePredicateNode = updateTypePredicateNode;
+    function createTypeReferenceNode(typeName, typeArguments) {
+        var node = createSynthesizedNode(159 /* TypeReference */);
+        node.typeName = asName(typeName);
+        node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments);
+        return node;
+    }
+    ts.createTypeReferenceNode = createTypeReferenceNode;
+    function updateTypeReferenceNode(node, typeName, typeArguments) {
+        return node.typeName !== typeName
+            || node.typeArguments !== typeArguments
+            ? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
+            : node;
+    }
+    ts.updateTypeReferenceNode = updateTypeReferenceNode;
+    function createFunctionTypeNode(typeParameters, parameters, type) {
+        return createSignatureDeclaration(160 /* FunctionType */, typeParameters, parameters, type);
+    }
+    ts.createFunctionTypeNode = createFunctionTypeNode;
+    function updateFunctionTypeNode(node, typeParameters, parameters, type) {
+        return updateSignatureDeclaration(node, typeParameters, parameters, type);
+    }
+    ts.updateFunctionTypeNode = updateFunctionTypeNode;
+    function createConstructorTypeNode(typeParameters, parameters, type) {
+        return createSignatureDeclaration(161 /* ConstructorType */, typeParameters, parameters, type);
+    }
+    ts.createConstructorTypeNode = createConstructorTypeNode;
+    function updateConstructorTypeNode(node, typeParameters, parameters, type) {
+        return updateSignatureDeclaration(node, typeParameters, parameters, type);
+    }
+    ts.updateConstructorTypeNode = updateConstructorTypeNode;
+    function createTypeQueryNode(exprName) {
+        var node = createSynthesizedNode(162 /* TypeQuery */);
+        node.exprName = exprName;
+        return node;
+    }
+    ts.createTypeQueryNode = createTypeQueryNode;
+    function updateTypeQueryNode(node, exprName) {
+        return node.exprName !== exprName
+            ? updateNode(createTypeQueryNode(exprName), node)
+            : node;
+    }
+    ts.updateTypeQueryNode = updateTypeQueryNode;
+    function createTypeLiteralNode(members) {
+        var node = createSynthesizedNode(163 /* TypeLiteral */);
+        node.members = createNodeArray(members);
+        return node;
+    }
+    ts.createTypeLiteralNode = createTypeLiteralNode;
+    function updateTypeLiteralNode(node, members) {
+        return node.members !== members
+            ? updateNode(createTypeLiteralNode(members), node)
+            : node;
+    }
+    ts.updateTypeLiteralNode = updateTypeLiteralNode;
+    function createArrayTypeNode(elementType) {
+        var node = createSynthesizedNode(164 /* ArrayType */);
+        node.elementType = ts.parenthesizeArrayTypeMember(elementType);
+        return node;
+    }
+    ts.createArrayTypeNode = createArrayTypeNode;
+    function updateArrayTypeNode(node, elementType) {
+        return node.elementType !== elementType
+            ? updateNode(createArrayTypeNode(elementType), node)
+            : node;
+    }
+    ts.updateArrayTypeNode = updateArrayTypeNode;
+    function createTupleTypeNode(elementTypes) {
+        var node = createSynthesizedNode(165 /* TupleType */);
+        node.elementTypes = createNodeArray(elementTypes);
+        return node;
+    }
+    ts.createTupleTypeNode = createTupleTypeNode;
+    function updateTypleTypeNode(node, elementTypes) {
+        return node.elementTypes !== elementTypes
+            ? updateNode(createTupleTypeNode(elementTypes), node)
+            : node;
+    }
+    ts.updateTypleTypeNode = updateTypleTypeNode;
+    function createUnionTypeNode(types) {
+        return createUnionOrIntersectionTypeNode(166 /* UnionType */, types);
+    }
+    ts.createUnionTypeNode = createUnionTypeNode;
+    function updateUnionTypeNode(node, types) {
+        return updateUnionOrIntersectionTypeNode(node, types);
+    }
+    ts.updateUnionTypeNode = updateUnionTypeNode;
+    function createIntersectionTypeNode(types) {
+        return createUnionOrIntersectionTypeNode(167 /* IntersectionType */, types);
+    }
+    ts.createIntersectionTypeNode = createIntersectionTypeNode;
+    function updateIntersectionTypeNode(node, types) {
+        return updateUnionOrIntersectionTypeNode(node, types);
+    }
+    ts.updateIntersectionTypeNode = updateIntersectionTypeNode;
+    function createUnionOrIntersectionTypeNode(kind, types) {
+        var node = createSynthesizedNode(kind);
+        node.types = ts.parenthesizeElementTypeMembers(types);
+        return node;
+    }
+    ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode;
+    function updateUnionOrIntersectionTypeNode(node, types) {
+        return node.types !== types
+            ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
+            : node;
+    }
+    function createParenthesizedType(type) {
+        var node = createSynthesizedNode(168 /* ParenthesizedType */);
+        node.type = type;
+        return node;
+    }
+    ts.createParenthesizedType = createParenthesizedType;
+    function updateParenthesizedType(node, type) {
+        return node.type !== type
+            ? updateNode(createParenthesizedType(type), node)
+            : node;
+    }
+    ts.updateParenthesizedType = updateParenthesizedType;
+    function createThisTypeNode() {
+        return createSynthesizedNode(169 /* ThisType */);
+    }
+    ts.createThisTypeNode = createThisTypeNode;
+    function createTypeOperatorNode(type) {
+        var node = createSynthesizedNode(170 /* TypeOperator */);
+        node.operator = 127 /* KeyOfKeyword */;
+        node.type = ts.parenthesizeElementTypeMember(type);
+        return node;
+    }
+    ts.createTypeOperatorNode = createTypeOperatorNode;
+    function updateTypeOperatorNode(node, type) {
+        return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node;
+    }
+    ts.updateTypeOperatorNode = updateTypeOperatorNode;
+    function createIndexedAccessTypeNode(objectType, indexType) {
+        var node = createSynthesizedNode(171 /* IndexedAccessType */);
+        node.objectType = ts.parenthesizeElementTypeMember(objectType);
+        node.indexType = indexType;
+        return node;
+    }
+    ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode;
+    function updateIndexedAccessTypeNode(node, objectType, indexType) {
+        return node.objectType !== objectType
+            || node.indexType !== indexType
+            ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
+            : node;
+    }
+    ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode;
+    function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) {
+        var node = createSynthesizedNode(172 /* MappedType */);
+        node.readonlyToken = readonlyToken;
+        node.typeParameter = typeParameter;
+        node.questionToken = questionToken;
+        node.type = type;
+        return node;
+    }
+    ts.createMappedTypeNode = createMappedTypeNode;
+    function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) {
+        return node.readonlyToken !== readonlyToken
+            || node.typeParameter !== typeParameter
+            || node.questionToken !== questionToken
+            || node.type !== type
+            ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
+            : node;
+    }
+    ts.updateMappedTypeNode = updateMappedTypeNode;
+    function createLiteralTypeNode(literal) {
+        var node = createSynthesizedNode(173 /* LiteralType */);
+        node.literal = literal;
+        return node;
+    }
+    ts.createLiteralTypeNode = createLiteralTypeNode;
+    function updateLiteralTypeNode(node, literal) {
+        return node.literal !== literal
+            ? updateNode(createLiteralTypeNode(literal), node)
+            : node;
+    }
+    ts.updateLiteralTypeNode = updateLiteralTypeNode;
+    // Binding Patterns
+    function createObjectBindingPattern(elements) {
+        var node = createSynthesizedNode(174 /* ObjectBindingPattern */);
+        node.elements = createNodeArray(elements);
+        return node;
+    }
+    ts.createObjectBindingPattern = createObjectBindingPattern;
+    function updateObjectBindingPattern(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createObjectBindingPattern(elements), node)
+            : node;
+    }
+    ts.updateObjectBindingPattern = updateObjectBindingPattern;
+    function createArrayBindingPattern(elements) {
+        var node = createSynthesizedNode(175 /* ArrayBindingPattern */);
+        node.elements = createNodeArray(elements);
+        return node;
+    }
+    ts.createArrayBindingPattern = createArrayBindingPattern;
+    function updateArrayBindingPattern(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createArrayBindingPattern(elements), node)
+            : node;
+    }
+    ts.updateArrayBindingPattern = updateArrayBindingPattern;
+    function createBindingElement(dotDotDotToken, propertyName, name, initializer) {
+        var node = createSynthesizedNode(176 /* BindingElement */);
+        node.dotDotDotToken = dotDotDotToken;
+        node.propertyName = asName(propertyName);
+        node.name = asName(name);
+        node.initializer = initializer;
+        return node;
+    }
+    ts.createBindingElement = createBindingElement;
+    function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) {
+        return node.propertyName !== propertyName
+            || node.dotDotDotToken !== dotDotDotToken
+            || node.name !== name
+            || node.initializer !== initializer
+            ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
+            : node;
+    }
+    ts.updateBindingElement = updateBindingElement;
+    // Expression
+    function createArrayLiteral(elements, multiLine) {
+        var node = createSynthesizedNode(177 /* ArrayLiteralExpression */);
+        node.elements = ts.parenthesizeListElements(createNodeArray(elements));
+        if (multiLine)
+            node.multiLine = true;
+        return node;
+    }
+    ts.createArrayLiteral = createArrayLiteral;
+    function updateArrayLiteral(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createArrayLiteral(elements, node.multiLine), node)
+            : node;
+    }
+    ts.updateArrayLiteral = updateArrayLiteral;
+    function createObjectLiteral(properties, multiLine) {
+        var node = createSynthesizedNode(178 /* ObjectLiteralExpression */);
+        node.properties = createNodeArray(properties);
+        if (multiLine)
+            node.multiLine = true;
+        return node;
+    }
+    ts.createObjectLiteral = createObjectLiteral;
+    function updateObjectLiteral(node, properties) {
+        return node.properties !== properties
+            ? updateNode(createObjectLiteral(properties, node.multiLine), node)
+            : node;
+    }
+    ts.updateObjectLiteral = updateObjectLiteral;
+    function createPropertyAccess(expression, name) {
+        var node = createSynthesizedNode(179 /* PropertyAccessExpression */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        node.name = asName(name);
+        setEmitFlags(node, 131072 /* NoIndentation */);
+        return node;
+    }
+    ts.createPropertyAccess = createPropertyAccess;
+    function updatePropertyAccess(node, expression, name) {
+        // Because we are updating existed propertyAccess we want to inherit its emitFlags
+        // instead of using the default from createPropertyAccess
+        return node.expression !== expression
+            || node.name !== name
+            ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node)
+            : node;
+    }
+    ts.updatePropertyAccess = updatePropertyAccess;
+    function createElementAccess(expression, index) {
+        var node = createSynthesizedNode(180 /* ElementAccessExpression */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        node.argumentExpression = asExpression(index);
+        return node;
+    }
+    ts.createElementAccess = createElementAccess;
+    function updateElementAccess(node, expression, argumentExpression) {
+        return node.expression !== expression
+            || node.argumentExpression !== argumentExpression
+            ? updateNode(createElementAccess(expression, argumentExpression), node)
+            : node;
+    }
+    ts.updateElementAccess = updateElementAccess;
+    function createCall(expression, typeArguments, argumentsArray) {
+        var node = createSynthesizedNode(181 /* CallExpression */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        node.typeArguments = asNodeArray(typeArguments);
+        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
+        return node;
+    }
+    ts.createCall = createCall;
+    function updateCall(node, expression, typeArguments, argumentsArray) {
+        return node.expression !== expression
+            || node.typeArguments !== typeArguments
+            || node.arguments !== argumentsArray
+            ? updateNode(createCall(expression, typeArguments, argumentsArray), node)
+            : node;
+    }
+    ts.updateCall = updateCall;
+    function createNew(expression, typeArguments, argumentsArray) {
+        var node = createSynthesizedNode(182 /* NewExpression */);
+        node.expression = ts.parenthesizeForNew(expression);
+        node.typeArguments = asNodeArray(typeArguments);
+        node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
+        return node;
+    }
+    ts.createNew = createNew;
+    function updateNew(node, expression, typeArguments, argumentsArray) {
+        return node.expression !== expression
+            || node.typeArguments !== typeArguments
+            || node.arguments !== argumentsArray
+            ? updateNode(createNew(expression, typeArguments, argumentsArray), node)
+            : node;
+    }
+    ts.updateNew = updateNew;
+    function createTaggedTemplate(tag, template) {
+        var node = createSynthesizedNode(183 /* TaggedTemplateExpression */);
+        node.tag = ts.parenthesizeForAccess(tag);
+        node.template = template;
+        return node;
+    }
+    ts.createTaggedTemplate = createTaggedTemplate;
+    function updateTaggedTemplate(node, tag, template) {
+        return node.tag !== tag
+            || node.template !== template
+            ? updateNode(createTaggedTemplate(tag, template), node)
+            : node;
+    }
+    ts.updateTaggedTemplate = updateTaggedTemplate;
+    function createTypeAssertion(type, expression) {
+        var node = createSynthesizedNode(184 /* TypeAssertionExpression */);
+        node.type = type;
+        node.expression = ts.parenthesizePrefixOperand(expression);
+        return node;
+    }
+    ts.createTypeAssertion = createTypeAssertion;
+    function updateTypeAssertion(node, type, expression) {
+        return node.type !== type
+            || node.expression !== expression
+            ? updateNode(createTypeAssertion(type, expression), node)
+            : node;
+    }
+    ts.updateTypeAssertion = updateTypeAssertion;
+    function createParen(expression) {
+        var node = createSynthesizedNode(185 /* ParenthesizedExpression */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createParen = createParen;
+    function updateParen(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createParen(expression), node)
+            : node;
+    }
+    ts.updateParen = updateParen;
+    function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
+        var node = createSynthesizedNode(186 /* FunctionExpression */);
+        node.modifiers = asNodeArray(modifiers);
+        node.asteriskToken = asteriskToken;
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        node.body = body;
+        return node;
+    }
+    ts.createFunctionExpression = createFunctionExpression;
+    function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
+        return node.name !== name
+            || node.modifiers !== modifiers
+            || node.asteriskToken !== asteriskToken
+            || node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.body !== body
+            ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
+            : node;
+    }
+    ts.updateFunctionExpression = updateFunctionExpression;
+    function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
+        var node = createSynthesizedNode(187 /* ArrowFunction */);
+        node.modifiers = asNodeArray(modifiers);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(36 /* EqualsGreaterThanToken */);
+        node.body = ts.parenthesizeConciseBody(body);
+        return node;
+    }
+    ts.createArrowFunction = createArrowFunction;
+    function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) {
+        var equalsGreaterThanToken;
+        var body;
+        if (bodyOrUndefined === undefined) {
+            equalsGreaterThanToken = node.equalsGreaterThanToken;
+            body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody);
+        }
+        else {
+            equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) {
+                return n.kind === 36 /* EqualsGreaterThanToken */;
+            });
+            body = bodyOrUndefined;
+        }
+        return node.modifiers !== modifiers
+            || node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.equalsGreaterThanToken !== equalsGreaterThanToken
+            || node.body !== body
+            ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
+            : node;
+    }
+    ts.updateArrowFunction = updateArrowFunction;
+    function createDelete(expression) {
+        var node = createSynthesizedNode(188 /* DeleteExpression */);
+        node.expression = ts.parenthesizePrefixOperand(expression);
+        return node;
+    }
+    ts.createDelete = createDelete;
+    function updateDelete(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createDelete(expression), node)
+            : node;
+    }
+    ts.updateDelete = updateDelete;
+    function createTypeOf(expression) {
+        var node = createSynthesizedNode(189 /* TypeOfExpression */);
+        node.expression = ts.parenthesizePrefixOperand(expression);
+        return node;
+    }
+    ts.createTypeOf = createTypeOf;
+    function updateTypeOf(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createTypeOf(expression), node)
+            : node;
+    }
+    ts.updateTypeOf = updateTypeOf;
+    function createVoid(expression) {
+        var node = createSynthesizedNode(190 /* VoidExpression */);
+        node.expression = ts.parenthesizePrefixOperand(expression);
+        return node;
+    }
+    ts.createVoid = createVoid;
+    function updateVoid(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createVoid(expression), node)
+            : node;
+    }
+    ts.updateVoid = updateVoid;
+    function createAwait(expression) {
+        var node = createSynthesizedNode(191 /* AwaitExpression */);
+        node.expression = ts.parenthesizePrefixOperand(expression);
+        return node;
+    }
+    ts.createAwait = createAwait;
+    function updateAwait(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createAwait(expression), node)
+            : node;
+    }
+    ts.updateAwait = updateAwait;
+    function createPrefix(operator, operand) {
+        var node = createSynthesizedNode(192 /* PrefixUnaryExpression */);
+        node.operator = operator;
+        node.operand = ts.parenthesizePrefixOperand(operand);
+        return node;
+    }
+    ts.createPrefix = createPrefix;
+    function updatePrefix(node, operand) {
+        return node.operand !== operand
+            ? updateNode(createPrefix(node.operator, operand), node)
+            : node;
+    }
+    ts.updatePrefix = updatePrefix;
+    function createPostfix(operand, operator) {
+        var node = createSynthesizedNode(193 /* PostfixUnaryExpression */);
+        node.operand = ts.parenthesizePostfixOperand(operand);
+        node.operator = operator;
+        return node;
+    }
+    ts.createPostfix = createPostfix;
+    function updatePostfix(node, operand) {
+        return node.operand !== operand
+            ? updateNode(createPostfix(operand, node.operator), node)
+            : node;
+    }
+    ts.updatePostfix = updatePostfix;
+    function createBinary(left, operator, right) {
+        var node = createSynthesizedNode(194 /* BinaryExpression */);
+        var operatorToken = asToken(operator);
+        var operatorKind = operatorToken.kind;
+        node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
+        node.operatorToken = operatorToken;
+        node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left);
+        return node;
+    }
+    ts.createBinary = createBinary;
+    function updateBinary(node, left, right, operator) {
+        return node.left !== left
+            || node.right !== right
+            ? updateNode(createBinary(left, operator || node.operatorToken, right), node)
+            : node;
+    }
+    ts.updateBinary = updateBinary;
+    function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) {
+        var node = createSynthesizedNode(195 /* ConditionalExpression */);
+        node.condition = ts.parenthesizeForConditionalHead(condition);
+        node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(55 /* QuestionToken */);
+        node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue);
+        node.colonToken = whenFalse ? colonToken : createToken(56 /* ColonToken */);
+        node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
+        return node;
+    }
+    ts.createConditional = createConditional;
+    function updateConditional(node, condition) {
+        var args = [];
+        for (var _i = 2; _i < arguments.length; _i++) {
+            args[_i - 2] = arguments[_i];
+        }
+        if (args.length === 2) {
+            var whenTrue_1 = args[0], whenFalse_1 = args[1];
+            return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1);
+        }
+        ts.Debug.assert(args.length === 4);
+        var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3];
+        return node.condition !== condition
+            || node.questionToken !== questionToken
+            || node.whenTrue !== whenTrue
+            || node.colonToken !== colonToken
+            || node.whenFalse !== whenFalse
+            ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
+            : node;
+    }
+    ts.updateConditional = updateConditional;
+    function createTemplateExpression(head, templateSpans) {
+        var node = createSynthesizedNode(196 /* TemplateExpression */);
+        node.head = head;
+        node.templateSpans = createNodeArray(templateSpans);
+        return node;
+    }
+    ts.createTemplateExpression = createTemplateExpression;
+    function updateTemplateExpression(node, head, templateSpans) {
+        return node.head !== head
+            || node.templateSpans !== templateSpans
+            ? updateNode(createTemplateExpression(head, templateSpans), node)
+            : node;
+    }
+    ts.updateTemplateExpression = updateTemplateExpression;
+    function createTemplateHead(text) {
+        var node = createSynthesizedNode(14 /* TemplateHead */);
+        node.text = text;
+        return node;
+    }
+    ts.createTemplateHead = createTemplateHead;
+    function createTemplateMiddle(text) {
+        var node = createSynthesizedNode(15 /* TemplateMiddle */);
+        node.text = text;
+        return node;
+    }
+    ts.createTemplateMiddle = createTemplateMiddle;
+    function createTemplateTail(text) {
+        var node = createSynthesizedNode(16 /* TemplateTail */);
+        node.text = text;
+        return node;
+    }
+    ts.createTemplateTail = createTemplateTail;
+    function createNoSubstitutionTemplateLiteral(text) {
+        var node = createSynthesizedNode(13 /* NoSubstitutionTemplateLiteral */);
+        node.text = text;
+        return node;
+    }
+    ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral;
+    function createYield(asteriskTokenOrExpression, expression) {
+        var node = createSynthesizedNode(197 /* YieldExpression */);
+        node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 39 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined;
+        node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 39 /* AsteriskToken */ ? asteriskTokenOrExpression : expression;
+        return node;
+    }
+    ts.createYield = createYield;
+    function updateYield(node, asteriskToken, expression) {
+        return node.expression !== expression
+            || node.asteriskToken !== asteriskToken
+            ? updateNode(createYield(asteriskToken, expression), node)
+            : node;
+    }
+    ts.updateYield = updateYield;
+    function createSpread(expression) {
+        var node = createSynthesizedNode(198 /* SpreadElement */);
+        node.expression = ts.parenthesizeExpressionForList(expression);
+        return node;
+    }
+    ts.createSpread = createSpread;
+    function updateSpread(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createSpread(expression), node)
+            : node;
+    }
+    ts.updateSpread = updateSpread;
+    function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) {
+        var node = createSynthesizedNode(199 /* ClassExpression */);
+        node.decorators = undefined;
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.heritageClauses = asNodeArray(heritageClauses);
+        node.members = createNodeArray(members);
+        return node;
+    }
+    ts.createClassExpression = createClassExpression;
+    function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) {
+        return node.modifiers !== modifiers
+            || node.name !== name
+            || node.typeParameters !== typeParameters
+            || node.heritageClauses !== heritageClauses
+            || node.members !== members
+            ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node)
+            : node;
+    }
+    ts.updateClassExpression = updateClassExpression;
+    function createOmittedExpression() {
+        return createSynthesizedNode(200 /* OmittedExpression */);
+    }
+    ts.createOmittedExpression = createOmittedExpression;
+    function createExpressionWithTypeArguments(typeArguments, expression) {
+        var node = createSynthesizedNode(201 /* ExpressionWithTypeArguments */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        node.typeArguments = asNodeArray(typeArguments);
+        return node;
+    }
+    ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments;
+    function updateExpressionWithTypeArguments(node, typeArguments, expression) {
+        return node.typeArguments !== typeArguments
+            || node.expression !== expression
+            ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
+            : node;
+    }
+    ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments;
+    function createAsExpression(expression, type) {
+        var node = createSynthesizedNode(202 /* AsExpression */);
+        node.expression = expression;
+        node.type = type;
+        return node;
+    }
+    ts.createAsExpression = createAsExpression;
+    function updateAsExpression(node, expression, type) {
+        return node.expression !== expression
+            || node.type !== type
+            ? updateNode(createAsExpression(expression, type), node)
+            : node;
+    }
+    ts.updateAsExpression = updateAsExpression;
+    function createNonNullExpression(expression) {
+        var node = createSynthesizedNode(203 /* NonNullExpression */);
+        node.expression = ts.parenthesizeForAccess(expression);
+        return node;
+    }
+    ts.createNonNullExpression = createNonNullExpression;
+    function updateNonNullExpression(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createNonNullExpression(expression), node)
+            : node;
+    }
+    ts.updateNonNullExpression = updateNonNullExpression;
+    function createMetaProperty(keywordToken, name) {
+        var node = createSynthesizedNode(204 /* MetaProperty */);
+        node.keywordToken = keywordToken;
+        node.name = name;
+        return node;
+    }
+    ts.createMetaProperty = createMetaProperty;
+    function updateMetaProperty(node, name) {
+        return node.name !== name
+            ? updateNode(createMetaProperty(node.keywordToken, name), node)
+            : node;
+    }
+    ts.updateMetaProperty = updateMetaProperty;
+    // Misc
+    function createTemplateSpan(expression, literal) {
+        var node = createSynthesizedNode(205 /* TemplateSpan */);
+        node.expression = expression;
+        node.literal = literal;
+        return node;
+    }
+    ts.createTemplateSpan = createTemplateSpan;
+    function updateTemplateSpan(node, expression, literal) {
+        return node.expression !== expression
+            || node.literal !== literal
+            ? updateNode(createTemplateSpan(expression, literal), node)
+            : node;
+    }
+    ts.updateTemplateSpan = updateTemplateSpan;
+    function createSemicolonClassElement() {
+        return createSynthesizedNode(206 /* SemicolonClassElement */);
+    }
+    ts.createSemicolonClassElement = createSemicolonClassElement;
+    // Element
+    function createBlock(statements, multiLine) {
+        var block = createSynthesizedNode(207 /* Block */);
+        block.statements = createNodeArray(statements);
+        if (multiLine)
+            block.multiLine = multiLine;
+        return block;
+    }
+    ts.createBlock = createBlock;
+    function updateBlock(node, statements) {
+        return node.statements !== statements
+            ? updateNode(createBlock(statements, node.multiLine), node)
+            : node;
+    }
+    ts.updateBlock = updateBlock;
+    function createVariableStatement(modifiers, declarationList) {
+        var node = createSynthesizedNode(208 /* VariableStatement */);
+        node.decorators = undefined;
+        node.modifiers = asNodeArray(modifiers);
+        node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
+        return node;
+    }
+    ts.createVariableStatement = createVariableStatement;
+    function updateVariableStatement(node, modifiers, declarationList) {
+        return node.modifiers !== modifiers
+            || node.declarationList !== declarationList
+            ? updateNode(createVariableStatement(modifiers, declarationList), node)
+            : node;
+    }
+    ts.updateVariableStatement = updateVariableStatement;
+    function createEmptyStatement() {
+        return createSynthesizedNode(209 /* EmptyStatement */);
+    }
+    ts.createEmptyStatement = createEmptyStatement;
+    function createStatement(expression) {
+        var node = createSynthesizedNode(210 /* ExpressionStatement */);
+        node.expression = ts.parenthesizeExpressionForExpressionStatement(expression);
+        return node;
+    }
+    ts.createStatement = createStatement;
+    function updateStatement(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createStatement(expression), node)
+            : node;
+    }
+    ts.updateStatement = updateStatement;
+    function createIf(expression, thenStatement, elseStatement) {
+        var node = createSynthesizedNode(211 /* IfStatement */);
+        node.expression = expression;
+        node.thenStatement = thenStatement;
+        node.elseStatement = elseStatement;
+        return node;
+    }
+    ts.createIf = createIf;
+    function updateIf(node, expression, thenStatement, elseStatement) {
+        return node.expression !== expression
+            || node.thenStatement !== thenStatement
+            || node.elseStatement !== elseStatement
+            ? updateNode(createIf(expression, thenStatement, elseStatement), node)
+            : node;
+    }
+    ts.updateIf = updateIf;
+    function createDo(statement, expression) {
+        var node = createSynthesizedNode(212 /* DoStatement */);
+        node.statement = statement;
+        node.expression = expression;
+        return node;
+    }
+    ts.createDo = createDo;
+    function updateDo(node, statement, expression) {
+        return node.statement !== statement
+            || node.expression !== expression
+            ? updateNode(createDo(statement, expression), node)
+            : node;
+    }
+    ts.updateDo = updateDo;
+    function createWhile(expression, statement) {
+        var node = createSynthesizedNode(213 /* WhileStatement */);
+        node.expression = expression;
+        node.statement = statement;
+        return node;
+    }
+    ts.createWhile = createWhile;
+    function updateWhile(node, expression, statement) {
+        return node.expression !== expression
+            || node.statement !== statement
+            ? updateNode(createWhile(expression, statement), node)
+            : node;
+    }
+    ts.updateWhile = updateWhile;
+    function createFor(initializer, condition, incrementor, statement) {
+        var node = createSynthesizedNode(214 /* ForStatement */);
+        node.initializer = initializer;
+        node.condition = condition;
+        node.incrementor = incrementor;
+        node.statement = statement;
+        return node;
+    }
+    ts.createFor = createFor;
+    function updateFor(node, initializer, condition, incrementor, statement) {
+        return node.initializer !== initializer
+            || node.condition !== condition
+            || node.incrementor !== incrementor
+            || node.statement !== statement
+            ? updateNode(createFor(initializer, condition, incrementor, statement), node)
+            : node;
+    }
+    ts.updateFor = updateFor;
+    function createForIn(initializer, expression, statement) {
+        var node = createSynthesizedNode(215 /* ForInStatement */);
+        node.initializer = initializer;
+        node.expression = expression;
+        node.statement = statement;
+        return node;
+    }
+    ts.createForIn = createForIn;
+    function updateForIn(node, initializer, expression, statement) {
+        return node.initializer !== initializer
+            || node.expression !== expression
+            || node.statement !== statement
+            ? updateNode(createForIn(initializer, expression, statement), node)
+            : node;
+    }
+    ts.updateForIn = updateForIn;
+    function createForOf(awaitModifier, initializer, expression, statement) {
+        var node = createSynthesizedNode(216 /* ForOfStatement */);
+        node.awaitModifier = awaitModifier;
+        node.initializer = initializer;
+        node.expression = expression;
+        node.statement = statement;
+        return node;
+    }
+    ts.createForOf = createForOf;
+    function updateForOf(node, awaitModifier, initializer, expression, statement) {
+        return node.awaitModifier !== awaitModifier
+            || node.initializer !== initializer
+            || node.expression !== expression
+            || node.statement !== statement
+            ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
+            : node;
+    }
+    ts.updateForOf = updateForOf;
+    function createContinue(label) {
+        var node = createSynthesizedNode(217 /* ContinueStatement */);
+        node.label = asName(label);
+        return node;
+    }
+    ts.createContinue = createContinue;
+    function updateContinue(node, label) {
+        return node.label !== label
+            ? updateNode(createContinue(label), node)
+            : node;
+    }
+    ts.updateContinue = updateContinue;
+    function createBreak(label) {
+        var node = createSynthesizedNode(218 /* BreakStatement */);
+        node.label = asName(label);
+        return node;
+    }
+    ts.createBreak = createBreak;
+    function updateBreak(node, label) {
+        return node.label !== label
+            ? updateNode(createBreak(label), node)
+            : node;
+    }
+    ts.updateBreak = updateBreak;
+    function createReturn(expression) {
+        var node = createSynthesizedNode(219 /* ReturnStatement */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createReturn = createReturn;
+    function updateReturn(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createReturn(expression), node)
+            : node;
+    }
+    ts.updateReturn = updateReturn;
+    function createWith(expression, statement) {
+        var node = createSynthesizedNode(220 /* WithStatement */);
+        node.expression = expression;
+        node.statement = statement;
+        return node;
+    }
+    ts.createWith = createWith;
+    function updateWith(node, expression, statement) {
+        return node.expression !== expression
+            || node.statement !== statement
+            ? updateNode(createWith(expression, statement), node)
+            : node;
+    }
+    ts.updateWith = updateWith;
+    function createSwitch(expression, caseBlock) {
+        var node = createSynthesizedNode(221 /* SwitchStatement */);
+        node.expression = ts.parenthesizeExpressionForList(expression);
+        node.caseBlock = caseBlock;
+        return node;
+    }
+    ts.createSwitch = createSwitch;
+    function updateSwitch(node, expression, caseBlock) {
+        return node.expression !== expression
+            || node.caseBlock !== caseBlock
+            ? updateNode(createSwitch(expression, caseBlock), node)
+            : node;
+    }
+    ts.updateSwitch = updateSwitch;
+    function createLabel(label, statement) {
+        var node = createSynthesizedNode(222 /* LabeledStatement */);
+        node.label = asName(label);
+        node.statement = statement;
+        return node;
+    }
+    ts.createLabel = createLabel;
+    function updateLabel(node, label, statement) {
+        return node.label !== label
+            || node.statement !== statement
+            ? updateNode(createLabel(label, statement), node)
+            : node;
+    }
+    ts.updateLabel = updateLabel;
+    function createThrow(expression) {
+        var node = createSynthesizedNode(223 /* ThrowStatement */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createThrow = createThrow;
+    function updateThrow(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createThrow(expression), node)
+            : node;
+    }
+    ts.updateThrow = updateThrow;
+    function createTry(tryBlock, catchClause, finallyBlock) {
+        var node = createSynthesizedNode(224 /* TryStatement */);
+        node.tryBlock = tryBlock;
+        node.catchClause = catchClause;
+        node.finallyBlock = finallyBlock;
+        return node;
+    }
+    ts.createTry = createTry;
+    function updateTry(node, tryBlock, catchClause, finallyBlock) {
+        return node.tryBlock !== tryBlock
+            || node.catchClause !== catchClause
+            || node.finallyBlock !== finallyBlock
+            ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node)
+            : node;
+    }
+    ts.updateTry = updateTry;
+    function createDebuggerStatement() {
+        return createSynthesizedNode(225 /* DebuggerStatement */);
+    }
+    ts.createDebuggerStatement = createDebuggerStatement;
+    function createVariableDeclaration(name, type, initializer) {
+        var node = createSynthesizedNode(226 /* VariableDeclaration */);
+        node.name = asName(name);
+        node.type = type;
+        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
+        return node;
+    }
+    ts.createVariableDeclaration = createVariableDeclaration;
+    function updateVariableDeclaration(node, name, type, initializer) {
+        return node.name !== name
+            || node.type !== type
+            || node.initializer !== initializer
+            ? updateNode(createVariableDeclaration(name, type, initializer), node)
+            : node;
+    }
+    ts.updateVariableDeclaration = updateVariableDeclaration;
+    function createVariableDeclarationList(declarations, flags) {
+        var node = createSynthesizedNode(227 /* VariableDeclarationList */);
+        node.flags |= flags & 3 /* BlockScoped */;
+        node.declarations = createNodeArray(declarations);
+        return node;
+    }
+    ts.createVariableDeclarationList = createVariableDeclarationList;
+    function updateVariableDeclarationList(node, declarations) {
+        return node.declarations !== declarations
+            ? updateNode(createVariableDeclarationList(declarations, node.flags), node)
+            : node;
+    }
+    ts.updateVariableDeclarationList = updateVariableDeclarationList;
+    function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
+        var node = createSynthesizedNode(228 /* FunctionDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.asteriskToken = asteriskToken;
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.parameters = createNodeArray(parameters);
+        node.type = type;
+        node.body = body;
+        return node;
+    }
+    ts.createFunctionDeclaration = createFunctionDeclaration;
+    function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.asteriskToken !== asteriskToken
+            || node.name !== name
+            || node.typeParameters !== typeParameters
+            || node.parameters !== parameters
+            || node.type !== type
+            || node.body !== body
+            ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
+            : node;
+    }
+    ts.updateFunctionDeclaration = updateFunctionDeclaration;
+    function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
+        var node = createSynthesizedNode(229 /* ClassDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.heritageClauses = asNodeArray(heritageClauses);
+        node.members = createNodeArray(members);
+        return node;
+    }
+    ts.createClassDeclaration = createClassDeclaration;
+    function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.typeParameters !== typeParameters
+            || node.heritageClauses !== heritageClauses
+            || node.members !== members
+            ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
+            : node;
+    }
+    ts.updateClassDeclaration = updateClassDeclaration;
+    function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
+        var node = createSynthesizedNode(230 /* InterfaceDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.heritageClauses = asNodeArray(heritageClauses);
+        node.members = createNodeArray(members);
+        return node;
+    }
+    ts.createInterfaceDeclaration = createInterfaceDeclaration;
+    function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.typeParameters !== typeParameters
+            || node.heritageClauses !== heritageClauses
+            || node.members !== members
+            ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
+            : node;
+    }
+    ts.updateInterfaceDeclaration = updateInterfaceDeclaration;
+    function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) {
+        var node = createSynthesizedNode(231 /* TypeAliasDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.typeParameters = asNodeArray(typeParameters);
+        node.type = type;
+        return node;
+    }
+    ts.createTypeAliasDeclaration = createTypeAliasDeclaration;
+    function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.typeParameters !== typeParameters
+            || node.type !== type
+            ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node)
+            : node;
+    }
+    ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration;
+    function createEnumDeclaration(decorators, modifiers, name, members) {
+        var node = createSynthesizedNode(232 /* EnumDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.members = createNodeArray(members);
+        return node;
+    }
+    ts.createEnumDeclaration = createEnumDeclaration;
+    function updateEnumDeclaration(node, decorators, modifiers, name, members) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.members !== members
+            ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node)
+            : node;
+    }
+    ts.updateEnumDeclaration = updateEnumDeclaration;
+    function createModuleDeclaration(decorators, modifiers, name, body, flags) {
+        var node = createSynthesizedNode(233 /* ModuleDeclaration */);
+        node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 512 /* GlobalAugmentation */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = name;
+        node.body = body;
+        return node;
+    }
+    ts.createModuleDeclaration = createModuleDeclaration;
+    function updateModuleDeclaration(node, decorators, modifiers, name, body) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.body !== body
+            ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node)
+            : node;
+    }
+    ts.updateModuleDeclaration = updateModuleDeclaration;
+    function createModuleBlock(statements) {
+        var node = createSynthesizedNode(234 /* ModuleBlock */);
+        node.statements = createNodeArray(statements);
+        return node;
+    }
+    ts.createModuleBlock = createModuleBlock;
+    function updateModuleBlock(node, statements) {
+        return node.statements !== statements
+            ? updateNode(createModuleBlock(statements), node)
+            : node;
+    }
+    ts.updateModuleBlock = updateModuleBlock;
+    function createCaseBlock(clauses) {
+        var node = createSynthesizedNode(235 /* CaseBlock */);
+        node.clauses = createNodeArray(clauses);
+        return node;
+    }
+    ts.createCaseBlock = createCaseBlock;
+    function updateCaseBlock(node, clauses) {
+        return node.clauses !== clauses
+            ? updateNode(createCaseBlock(clauses), node)
+            : node;
+    }
+    ts.updateCaseBlock = updateCaseBlock;
+    function createNamespaceExportDeclaration(name) {
+        var node = createSynthesizedNode(236 /* NamespaceExportDeclaration */);
+        node.name = asName(name);
+        return node;
+    }
+    ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration;
+    function updateNamespaceExportDeclaration(node, name) {
+        return node.name !== name
+            ? updateNode(createNamespaceExportDeclaration(name), node)
+            : node;
+    }
+    ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration;
+    function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) {
+        var node = createSynthesizedNode(237 /* ImportEqualsDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.name = asName(name);
+        node.moduleReference = moduleReference;
+        return node;
+    }
+    ts.createImportEqualsDeclaration = createImportEqualsDeclaration;
+    function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.name !== name
+            || node.moduleReference !== moduleReference
+            ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node)
+            : node;
+    }
+    ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration;
+    function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) {
+        var node = createSynthesizedNode(238 /* ImportDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.importClause = importClause;
+        node.moduleSpecifier = moduleSpecifier;
+        return node;
+    }
+    ts.createImportDeclaration = createImportDeclaration;
+    function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.importClause !== importClause
+            || node.moduleSpecifier !== moduleSpecifier
+            ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
+            : node;
+    }
+    ts.updateImportDeclaration = updateImportDeclaration;
+    function createImportClause(name, namedBindings) {
+        var node = createSynthesizedNode(239 /* ImportClause */);
+        node.name = name;
+        node.namedBindings = namedBindings;
+        return node;
+    }
+    ts.createImportClause = createImportClause;
+    function updateImportClause(node, name, namedBindings) {
+        return node.name !== name
+            || node.namedBindings !== namedBindings
+            ? updateNode(createImportClause(name, namedBindings), node)
+            : node;
+    }
+    ts.updateImportClause = updateImportClause;
+    function createNamespaceImport(name) {
+        var node = createSynthesizedNode(240 /* NamespaceImport */);
+        node.name = name;
+        return node;
+    }
+    ts.createNamespaceImport = createNamespaceImport;
+    function updateNamespaceImport(node, name) {
+        return node.name !== name
+            ? updateNode(createNamespaceImport(name), node)
+            : node;
+    }
+    ts.updateNamespaceImport = updateNamespaceImport;
+    function createNamedImports(elements) {
+        var node = createSynthesizedNode(241 /* NamedImports */);
+        node.elements = createNodeArray(elements);
+        return node;
+    }
+    ts.createNamedImports = createNamedImports;
+    function updateNamedImports(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createNamedImports(elements), node)
+            : node;
+    }
+    ts.updateNamedImports = updateNamedImports;
+    function createImportSpecifier(propertyName, name) {
+        var node = createSynthesizedNode(242 /* ImportSpecifier */);
+        node.propertyName = propertyName;
+        node.name = name;
+        return node;
+    }
+    ts.createImportSpecifier = createImportSpecifier;
+    function updateImportSpecifier(node, propertyName, name) {
+        return node.propertyName !== propertyName
+            || node.name !== name
+            ? updateNode(createImportSpecifier(propertyName, name), node)
+            : node;
+    }
+    ts.updateImportSpecifier = updateImportSpecifier;
+    function createExportAssignment(decorators, modifiers, isExportEquals, expression) {
+        var node = createSynthesizedNode(243 /* ExportAssignment */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.isExportEquals = isExportEquals;
+        node.expression = expression;
+        return node;
+    }
+    ts.createExportAssignment = createExportAssignment;
+    function updateExportAssignment(node, decorators, modifiers, expression) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.expression !== expression
+            ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node)
+            : node;
+    }
+    ts.updateExportAssignment = updateExportAssignment;
+    function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier) {
+        var node = createSynthesizedNode(244 /* ExportDeclaration */);
+        node.decorators = asNodeArray(decorators);
+        node.modifiers = asNodeArray(modifiers);
+        node.exportClause = exportClause;
+        node.moduleSpecifier = moduleSpecifier;
+        return node;
+    }
+    ts.createExportDeclaration = createExportDeclaration;
+    function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier) {
+        return node.decorators !== decorators
+            || node.modifiers !== modifiers
+            || node.exportClause !== exportClause
+            || node.moduleSpecifier !== moduleSpecifier
+            ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier), node)
+            : node;
+    }
+    ts.updateExportDeclaration = updateExportDeclaration;
+    function createNamedExports(elements) {
+        var node = createSynthesizedNode(245 /* NamedExports */);
+        node.elements = createNodeArray(elements);
+        return node;
+    }
+    ts.createNamedExports = createNamedExports;
+    function updateNamedExports(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createNamedExports(elements), node)
+            : node;
+    }
+    ts.updateNamedExports = updateNamedExports;
+    function createExportSpecifier(propertyName, name) {
+        var node = createSynthesizedNode(246 /* ExportSpecifier */);
+        node.propertyName = asName(propertyName);
+        node.name = asName(name);
+        return node;
+    }
+    ts.createExportSpecifier = createExportSpecifier;
+    function updateExportSpecifier(node, propertyName, name) {
+        return node.propertyName !== propertyName
+            || node.name !== name
+            ? updateNode(createExportSpecifier(propertyName, name), node)
+            : node;
+    }
+    ts.updateExportSpecifier = updateExportSpecifier;
+    // Module references
+    function createExternalModuleReference(expression) {
+        var node = createSynthesizedNode(248 /* ExternalModuleReference */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createExternalModuleReference = createExternalModuleReference;
+    function updateExternalModuleReference(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createExternalModuleReference(expression), node)
+            : node;
+    }
+    ts.updateExternalModuleReference = updateExternalModuleReference;
+    // JSX
+    function createJsxElement(openingElement, children, closingElement) {
+        var node = createSynthesizedNode(249 /* JsxElement */);
+        node.openingElement = openingElement;
+        node.children = createNodeArray(children);
+        node.closingElement = closingElement;
+        return node;
+    }
+    ts.createJsxElement = createJsxElement;
+    function updateJsxElement(node, openingElement, children, closingElement) {
+        return node.openingElement !== openingElement
+            || node.children !== children
+            || node.closingElement !== closingElement
+            ? updateNode(createJsxElement(openingElement, children, closingElement), node)
+            : node;
+    }
+    ts.updateJsxElement = updateJsxElement;
+    function createJsxSelfClosingElement(tagName, attributes) {
+        var node = createSynthesizedNode(250 /* JsxSelfClosingElement */);
+        node.tagName = tagName;
+        node.attributes = attributes;
+        return node;
+    }
+    ts.createJsxSelfClosingElement = createJsxSelfClosingElement;
+    function updateJsxSelfClosingElement(node, tagName, attributes) {
+        return node.tagName !== tagName
+            || node.attributes !== attributes
+            ? updateNode(createJsxSelfClosingElement(tagName, attributes), node)
+            : node;
+    }
+    ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement;
+    function createJsxOpeningElement(tagName, attributes) {
+        var node = createSynthesizedNode(251 /* JsxOpeningElement */);
+        node.tagName = tagName;
+        node.attributes = attributes;
+        return node;
+    }
+    ts.createJsxOpeningElement = createJsxOpeningElement;
+    function updateJsxOpeningElement(node, tagName, attributes) {
+        return node.tagName !== tagName
+            || node.attributes !== attributes
+            ? updateNode(createJsxOpeningElement(tagName, attributes), node)
+            : node;
+    }
+    ts.updateJsxOpeningElement = updateJsxOpeningElement;
+    function createJsxClosingElement(tagName) {
+        var node = createSynthesizedNode(252 /* JsxClosingElement */);
+        node.tagName = tagName;
+        return node;
+    }
+    ts.createJsxClosingElement = createJsxClosingElement;
+    function updateJsxClosingElement(node, tagName) {
+        return node.tagName !== tagName
+            ? updateNode(createJsxClosingElement(tagName), node)
+            : node;
+    }
+    ts.updateJsxClosingElement = updateJsxClosingElement;
+    function createJsxAttribute(name, initializer) {
+        var node = createSynthesizedNode(253 /* JsxAttribute */);
+        node.name = name;
+        node.initializer = initializer;
+        return node;
+    }
+    ts.createJsxAttribute = createJsxAttribute;
+    function updateJsxAttribute(node, name, initializer) {
+        return node.name !== name
+            || node.initializer !== initializer
+            ? updateNode(createJsxAttribute(name, initializer), node)
+            : node;
+    }
+    ts.updateJsxAttribute = updateJsxAttribute;
+    function createJsxAttributes(properties) {
+        var node = createSynthesizedNode(254 /* JsxAttributes */);
+        node.properties = createNodeArray(properties);
+        return node;
+    }
+    ts.createJsxAttributes = createJsxAttributes;
+    function updateJsxAttributes(node, properties) {
+        return node.properties !== properties
+            ? updateNode(createJsxAttributes(properties), node)
+            : node;
+    }
+    ts.updateJsxAttributes = updateJsxAttributes;
+    function createJsxSpreadAttribute(expression) {
+        var node = createSynthesizedNode(255 /* JsxSpreadAttribute */);
+        node.expression = expression;
+        return node;
+    }
+    ts.createJsxSpreadAttribute = createJsxSpreadAttribute;
+    function updateJsxSpreadAttribute(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createJsxSpreadAttribute(expression), node)
+            : node;
+    }
+    ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute;
+    function createJsxExpression(dotDotDotToken, expression) {
+        var node = createSynthesizedNode(256 /* JsxExpression */);
+        node.dotDotDotToken = dotDotDotToken;
+        node.expression = expression;
+        return node;
+    }
+    ts.createJsxExpression = createJsxExpression;
+    function updateJsxExpression(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
+            : node;
+    }
+    ts.updateJsxExpression = updateJsxExpression;
+    // Clauses
+    function createCaseClause(expression, statements) {
+        var node = createSynthesizedNode(257 /* CaseClause */);
+        node.expression = ts.parenthesizeExpressionForList(expression);
+        node.statements = createNodeArray(statements);
+        return node;
+    }
+    ts.createCaseClause = createCaseClause;
+    function updateCaseClause(node, expression, statements) {
+        return node.expression !== expression
+            || node.statements !== statements
+            ? updateNode(createCaseClause(expression, statements), node)
+            : node;
+    }
+    ts.updateCaseClause = updateCaseClause;
+    function createDefaultClause(statements) {
+        var node = createSynthesizedNode(258 /* DefaultClause */);
+        node.statements = createNodeArray(statements);
+        return node;
+    }
+    ts.createDefaultClause = createDefaultClause;
+    function updateDefaultClause(node, statements) {
+        return node.statements !== statements
+            ? updateNode(createDefaultClause(statements), node)
+            : node;
+    }
+    ts.updateDefaultClause = updateDefaultClause;
+    function createHeritageClause(token, types) {
+        var node = createSynthesizedNode(259 /* HeritageClause */);
+        node.token = token;
+        node.types = createNodeArray(types);
+        return node;
+    }
+    ts.createHeritageClause = createHeritageClause;
+    function updateHeritageClause(node, types) {
+        return node.types !== types
+            ? updateNode(createHeritageClause(node.token, types), node)
+            : node;
+    }
+    ts.updateHeritageClause = updateHeritageClause;
+    function createCatchClause(variableDeclaration, block) {
+        var node = createSynthesizedNode(260 /* CatchClause */);
+        node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
+        node.block = block;
+        return node;
+    }
+    ts.createCatchClause = createCatchClause;
+    function updateCatchClause(node, variableDeclaration, block) {
+        return node.variableDeclaration !== variableDeclaration
+            || node.block !== block
+            ? updateNode(createCatchClause(variableDeclaration, block), node)
+            : node;
+    }
+    ts.updateCatchClause = updateCatchClause;
+    // Property assignments
+    function createPropertyAssignment(name, initializer) {
+        var node = createSynthesizedNode(261 /* PropertyAssignment */);
+        node.name = asName(name);
+        node.questionToken = undefined;
+        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
+        return node;
+    }
+    ts.createPropertyAssignment = createPropertyAssignment;
+    function updatePropertyAssignment(node, name, initializer) {
+        return node.name !== name
+            || node.initializer !== initializer
+            ? updateNode(createPropertyAssignment(name, initializer), node)
+            : node;
+    }
+    ts.updatePropertyAssignment = updatePropertyAssignment;
+    function createShorthandPropertyAssignment(name, objectAssignmentInitializer) {
+        var node = createSynthesizedNode(262 /* ShorthandPropertyAssignment */);
+        node.name = asName(name);
+        node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
+        return node;
+    }
+    ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment;
+    function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) {
+        return node.name !== name
+            || node.objectAssignmentInitializer !== objectAssignmentInitializer
+            ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node)
+            : node;
+    }
+    ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment;
+    function createSpreadAssignment(expression) {
+        var node = createSynthesizedNode(263 /* SpreadAssignment */);
+        node.expression = expression !== undefined ? ts.parenthesizeExpressionForList(expression) : undefined;
+        return node;
+    }
+    ts.createSpreadAssignment = createSpreadAssignment;
+    function updateSpreadAssignment(node, expression) {
+        return node.expression !== expression
+            ? updateNode(createSpreadAssignment(expression), node)
+            : node;
+    }
+    ts.updateSpreadAssignment = updateSpreadAssignment;
+    // Enum
+    function createEnumMember(name, initializer) {
+        var node = createSynthesizedNode(264 /* EnumMember */);
+        node.name = asName(name);
+        node.initializer = initializer && ts.parenthesizeExpressionForList(initializer);
+        return node;
+    }
+    ts.createEnumMember = createEnumMember;
+    function updateEnumMember(node, name, initializer) {
+        return node.name !== name
+            || node.initializer !== initializer
+            ? updateNode(createEnumMember(name, initializer), node)
+            : node;
+    }
+    ts.updateEnumMember = updateEnumMember;
+    // Top-level nodes
+    function updateSourceFileNode(node, statements) {
+        if (node.statements !== statements) {
+            var updated = createSynthesizedNode(265 /* SourceFile */);
+            updated.flags |= node.flags;
+            updated.statements = createNodeArray(statements);
+            updated.endOfFileToken = node.endOfFileToken;
+            updated.fileName = node.fileName;
+            updated.path = node.path;
+            updated.text = node.text;
+            if (node.amdDependencies !== undefined)
+                updated.amdDependencies = node.amdDependencies;
+            if (node.moduleName !== undefined)
+                updated.moduleName = node.moduleName;
+            if (node.referencedFiles !== undefined)
+                updated.referencedFiles = node.referencedFiles;
+            if (node.typeReferenceDirectives !== undefined)
+                updated.typeReferenceDirectives = node.typeReferenceDirectives;
+            if (node.languageVariant !== undefined)
+                updated.languageVariant = node.languageVariant;
+            if (node.isDeclarationFile !== undefined)
+                updated.isDeclarationFile = node.isDeclarationFile;
+            if (node.renamedDependencies !== undefined)
+                updated.renamedDependencies = node.renamedDependencies;
+            if (node.hasNoDefaultLib !== undefined)
+                updated.hasNoDefaultLib = node.hasNoDefaultLib;
+            if (node.languageVersion !== undefined)
+                updated.languageVersion = node.languageVersion;
+            if (node.scriptKind !== undefined)
+                updated.scriptKind = node.scriptKind;
+            if (node.externalModuleIndicator !== undefined)
+                updated.externalModuleIndicator = node.externalModuleIndicator;
+            if (node.commonJsModuleIndicator !== undefined)
+                updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
+            if (node.identifiers !== undefined)
+                updated.identifiers = node.identifiers;
+            if (node.nodeCount !== undefined)
+                updated.nodeCount = node.nodeCount;
+            if (node.identifierCount !== undefined)
+                updated.identifierCount = node.identifierCount;
+            if (node.symbolCount !== undefined)
+                updated.symbolCount = node.symbolCount;
+            if (node.parseDiagnostics !== undefined)
+                updated.parseDiagnostics = node.parseDiagnostics;
+            if (node.bindDiagnostics !== undefined)
+                updated.bindDiagnostics = node.bindDiagnostics;
+            if (node.lineMap !== undefined)
+                updated.lineMap = node.lineMap;
+            if (node.classifiableNames !== undefined)
+                updated.classifiableNames = node.classifiableNames;
+            if (node.resolvedModules !== undefined)
+                updated.resolvedModules = node.resolvedModules;
+            if (node.resolvedTypeReferenceDirectiveNames !== undefined)
+                updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
+            if (node.imports !== undefined)
+                updated.imports = node.imports;
+            if (node.moduleAugmentations !== undefined)
+                updated.moduleAugmentations = node.moduleAugmentations;
+            return updateNode(updated, node);
+        }
+        return node;
+    }
+    ts.updateSourceFileNode = updateSourceFileNode;
+    /**
+     * Creates a shallow, memberwise clone of a node for mutation.
+     */
+    function getMutableClone(node) {
+        var clone = getSynthesizedClone(node);
+        clone.pos = node.pos;
+        clone.end = node.end;
+        clone.parent = node.parent;
+        return clone;
+    }
+    ts.getMutableClone = getMutableClone;
+    // Transformation nodes
+    /**
+     * Creates a synthetic statement to act as a placeholder for a not-emitted statement in
+     * order to preserve comments.
+     *
+     * @param original The original statement.
+     */
+    function createNotEmittedStatement(original) {
+        var node = createSynthesizedNode(287 /* NotEmittedStatement */);
+        node.original = original;
+        setTextRange(node, original);
+        return node;
+    }
+    ts.createNotEmittedStatement = createNotEmittedStatement;
+    /**
+     * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
+     * order to properly emit exports.
+     */
+    /* @internal */
+    function createEndOfDeclarationMarker(original) {
+        var node = createSynthesizedNode(291 /* EndOfDeclarationMarker */);
+        node.emitNode = {};
+        node.original = original;
+        return node;
+    }
+    ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker;
+    /**
+     * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
+     * order to properly emit exports.
+     */
+    /* @internal */
+    function createMergeDeclarationMarker(original) {
+        var node = createSynthesizedNode(290 /* MergeDeclarationMarker */);
+        node.emitNode = {};
+        node.original = original;
+        return node;
+    }
+    ts.createMergeDeclarationMarker = createMergeDeclarationMarker;
+    /**
+     * Creates a synthetic expression to act as a placeholder for a not-emitted expression in
+     * order to preserve comments or sourcemap positions.
+     *
+     * @param expression The inner expression to emit.
+     * @param original The original outer expression.
+     * @param location The location for the expression. Defaults to the positions from "original" if provided.
+     */
+    function createPartiallyEmittedExpression(expression, original) {
+        var node = createSynthesizedNode(288 /* PartiallyEmittedExpression */);
+        node.expression = expression;
+        node.original = original;
+        setTextRange(node, original);
+        return node;
+    }
+    ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression;
+    function updatePartiallyEmittedExpression(node, expression) {
+        if (node.expression !== expression) {
+            return updateNode(createPartiallyEmittedExpression(expression, node.original), node);
+        }
+        return node;
+    }
+    ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression;
+    function flattenCommaElements(node) {
+        if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
+            if (node.kind === 289 /* CommaListExpression */) {
+                return node.elements;
+            }
+            if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) {
+                return [node.left, node.right];
+            }
+        }
+        return node;
+    }
+    function createCommaList(elements) {
+        var node = createSynthesizedNode(289 /* CommaListExpression */);
+        node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements));
+        return node;
+    }
+    ts.createCommaList = createCommaList;
+    function updateCommaList(node, elements) {
+        return node.elements !== elements
+            ? updateNode(createCommaList(elements), node)
+            : node;
+    }
+    ts.updateCommaList = updateCommaList;
+    function createBundle(sourceFiles) {
+        var node = ts.createNode(266 /* Bundle */);
+        node.sourceFiles = sourceFiles;
+        return node;
+    }
+    ts.createBundle = createBundle;
+    function updateBundle(node, sourceFiles) {
+        if (node.sourceFiles !== sourceFiles) {
+            return createBundle(sourceFiles);
+        }
+        return node;
+    }
+    ts.updateBundle = updateBundle;
+    function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) {
+        return createCall(createFunctionExpression(
+        /*modifiers*/ undefined, 
+        /*asteriskToken*/ undefined, 
+        /*name*/ undefined, 
+        /*typeParameters*/ undefined, 
+        /*parameters*/ param ? [param] : [], 
+        /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), 
+        /*typeArguments*/ undefined, 
+        /*argumentsArray*/ paramValue ? [paramValue] : []);
+    }
+    ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
+    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
+        return createCall(createArrowFunction(
+        /*modifiers*/ undefined, 
+        /*typeParameters*/ undefined, 
+        /*parameters*/ param ? [param] : [], 
+        /*type*/ undefined, 
+        /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), 
+        /*typeArguments*/ undefined, 
+        /*argumentsArray*/ paramValue ? [paramValue] : []);
+    }
+    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
+    function createComma(left, right) {
+        return createBinary(left, 26 /* CommaToken */, right);
+    }
+    ts.createComma = createComma;
+    function createLessThan(left, right) {
+        return createBinary(left, 27 /* LessThanToken */, right);
+    }
+    ts.createLessThan = createLessThan;
+    function createAssignment(left, right) {
+        return createBinary(left, 58 /* EqualsToken */, right);
+    }
+    ts.createAssignment = createAssignment;
+    function createStrictEquality(left, right) {
+        return createBinary(left, 34 /* EqualsEqualsEqualsToken */, right);
+    }
+    ts.createStrictEquality = createStrictEquality;
+    function createStrictInequality(left, right) {
+        return createBinary(left, 35 /* ExclamationEqualsEqualsToken */, right);
+    }
+    ts.createStrictInequality = createStrictInequality;
+    function createAdd(left, right) {
+        return createBinary(left, 37 /* PlusToken */, right);
+    }
+    ts.createAdd = createAdd;
+    function createSubtract(left, right) {
+        return createBinary(left, 38 /* MinusToken */, right);
+    }
+    ts.createSubtract = createSubtract;
+    function createPostfixIncrement(operand) {
+        return createPostfix(operand, 43 /* PlusPlusToken */);
+    }
+    ts.createPostfixIncrement = createPostfixIncrement;
+    function createLogicalAnd(left, right) {
+        return createBinary(left, 53 /* AmpersandAmpersandToken */, right);
+    }
+    ts.createLogicalAnd = createLogicalAnd;
+    function createLogicalOr(left, right) {
+        return createBinary(left, 54 /* BarBarToken */, right);
+    }
+    ts.createLogicalOr = createLogicalOr;
+    function createLogicalNot(operand) {
+        return createPrefix(51 /* ExclamationToken */, operand);
+    }
+    ts.createLogicalNot = createLogicalNot;
+    function createVoidZero() {
+        return createVoid(createLiteral(0));
+    }
+    ts.createVoidZero = createVoidZero;
+    function createExportDefault(expression) {
+        return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
+    }
+    ts.createExportDefault = createExportDefault;
+    function createExternalModuleExport(exportName) {
+        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
+    }
+    ts.createExternalModuleExport = createExternalModuleExport;
+    function asName(name) {
+        return ts.isString(name) ? createIdentifier(name) : name;
+    }
+    function asExpression(value) {
+        return ts.isString(value) || typeof value === "number" ? createLiteral(value) : value;
+    }
+    function asNodeArray(array) {
+        return array ? createNodeArray(array) : undefined;
+    }
+    function asToken(value) {
+        return typeof value === "number" ? createToken(value) : value;
+    }
+    /**
+     * Clears any EmitNode entries from parse-tree nodes.
+     * @param sourceFile A source file.
+     */
+    function disposeEmitNodes(sourceFile) {
+        // During transformation we may need to annotate a parse tree node with transient
+        // transformation properties. As parse tree nodes live longer than transformation
+        // nodes, we need to make sure we reclaim any memory allocated for custom ranges
+        // from these nodes to ensure we do not hold onto entire subtrees just for position
+        // information. We also need to reset these nodes to a pre-transformation state
+        // for incremental parsing scenarios so that we do not impact later emit.
+        sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile));
+        var emitNode = sourceFile && sourceFile.emitNode;
+        var annotatedNodes = emitNode && emitNode.annotatedNodes;
+        if (annotatedNodes) {
+            for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) {
+                var node = annotatedNodes_1[_i];
+                node.emitNode = undefined;
+            }
+        }
+    }
+    ts.disposeEmitNodes = disposeEmitNodes;
+    /**
+     * Associates a node with the current transformation, initializing
+     * various transient transformation properties.
+     */
+    /* @internal */
+    function getOrCreateEmitNode(node) {
+        if (!node.emitNode) {
+            if (ts.isParseTreeNode(node)) {
+                // To avoid holding onto transformation artifacts, we keep track of any
+                // parse tree node we are annotating. This allows us to clean them up after
+                // all transformations have completed.
+                if (node.kind === 265 /* SourceFile */) {
+                    return node.emitNode = { annotatedNodes: [node] };
+                }
+                var sourceFile = ts.getSourceFileOfNode(node);
+                getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
+            }
+            node.emitNode = {};
+        }
+        return node.emitNode;
+    }
+    ts.getOrCreateEmitNode = getOrCreateEmitNode;
+    function setTextRange(range, location) {
+        if (location) {
+            range.pos = location.pos;
+            range.end = location.end;
+        }
+        return range;
+    }
+    ts.setTextRange = setTextRange;
+    /**
+     * Sets flags that control emit behavior of a node.
+     */
+    function setEmitFlags(node, emitFlags) {
+        getOrCreateEmitNode(node).flags = emitFlags;
+        return node;
+    }
+    ts.setEmitFlags = setEmitFlags;
+    /**
+     * Sets flags that control emit behavior of a node.
+     */
+    /* @internal */
+    function addEmitFlags(node, emitFlags) {
+        var emitNode = getOrCreateEmitNode(node);
+        emitNode.flags = emitNode.flags | emitFlags;
+        return node;
+    }
+    ts.addEmitFlags = addEmitFlags;
+    /**
+     * Gets a custom text range to use when emitting source maps.
+     */
+    function getSourceMapRange(node) {
+        var emitNode = node.emitNode;
+        return (emitNode && emitNode.sourceMapRange) || node;
+    }
+    ts.getSourceMapRange = getSourceMapRange;
+    /**
+     * Sets a custom text range to use when emitting source maps.
+     */
+    function setSourceMapRange(node, range) {
+        getOrCreateEmitNode(node).sourceMapRange = range;
+        return node;
+    }
+    ts.setSourceMapRange = setSourceMapRange;
+    var SourceMapSource;
+    /**
+     * Create an external source map source file reference
+     */
+    function createSourceMapSource(fileName, text, skipTrivia) {
+        return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia);
+    }
+    ts.createSourceMapSource = createSourceMapSource;
+    /**
+     * Gets the TextRange to use for source maps for a token of a node.
+     */
+    function getTokenSourceMapRange(node, token) {
+        var emitNode = node.emitNode;
+        var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
+        return tokenSourceMapRanges && tokenSourceMapRanges[token];
+    }
+    ts.getTokenSourceMapRange = getTokenSourceMapRange;
+    /**
+     * Sets the TextRange to use for source maps for a token of a node.
+     */
+    function setTokenSourceMapRange(node, token, range) {
+        var emitNode = getOrCreateEmitNode(node);
+        var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
+        tokenSourceMapRanges[token] = range;
+        return node;
+    }
+    ts.setTokenSourceMapRange = setTokenSourceMapRange;
+    /**
+     * Gets a custom text range to use when emitting comments.
+     */
+    function getCommentRange(node) {
+        var emitNode = node.emitNode;
+        return (emitNode && emitNode.commentRange) || node;
+    }
+    ts.getCommentRange = getCommentRange;
+    /**
+     * Sets a custom text range to use when emitting comments.
+     */
+    function setCommentRange(node, range) {
+        getOrCreateEmitNode(node).commentRange = range;
+        return node;
+    }
+    ts.setCommentRange = setCommentRange;
+    function getSyntheticLeadingComments(node) {
+        var emitNode = node.emitNode;
+        return emitNode && emitNode.leadingComments;
+    }
+    ts.getSyntheticLeadingComments = getSyntheticLeadingComments;
+    function setSyntheticLeadingComments(node, comments) {
+        getOrCreateEmitNode(node).leadingComments = comments;
+        return node;
+    }
+    ts.setSyntheticLeadingComments = setSyntheticLeadingComments;
+    function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) {
+        return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
+    }
+    ts.addSyntheticLeadingComment = addSyntheticLeadingComment;
+    function getSyntheticTrailingComments(node) {
+        var emitNode = node.emitNode;
+        return emitNode && emitNode.trailingComments;
+    }
+    ts.getSyntheticTrailingComments = getSyntheticTrailingComments;
+    function setSyntheticTrailingComments(node, comments) {
+        getOrCreateEmitNode(node).trailingComments = comments;
+        return node;
+    }
+    ts.setSyntheticTrailingComments = setSyntheticTrailingComments;
+    function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) {
+        return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
+    }
+    ts.addSyntheticTrailingComment = addSyntheticTrailingComment;
+    /**
+     * Gets the constant value to emit for an expression.
+     */
+    function getConstantValue(node) {
+        var emitNode = node.emitNode;
+        return emitNode && emitNode.constantValue;
+    }
+    ts.getConstantValue = getConstantValue;
+    /**
+     * Sets the constant value to emit for an expression.
+     */
+    function setConstantValue(node, value) {
+        var emitNode = getOrCreateEmitNode(node);
+        emitNode.constantValue = value;
+        return node;
+    }
+    ts.setConstantValue = setConstantValue;
+    /**
+     * Adds an EmitHelper to a node.
+     */
+    function addEmitHelper(node, helper) {
+        var emitNode = getOrCreateEmitNode(node);
+        emitNode.helpers = ts.append(emitNode.helpers, helper);
+        return node;
+    }
+    ts.addEmitHelper = addEmitHelper;
+    /**
+     * Add EmitHelpers to a node.
+     */
+    function addEmitHelpers(node, helpers) {
+        if (ts.some(helpers)) {
+            var emitNode = getOrCreateEmitNode(node);
+            for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) {
+                var helper = helpers_1[_i];
+                emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper);
+            }
+        }
+        return node;
+    }
+    ts.addEmitHelpers = addEmitHelpers;
+    /**
+     * Removes an EmitHelper from a node.
+     */
+    function removeEmitHelper(node, helper) {
+        var emitNode = node.emitNode;
+        if (emitNode) {
+            var helpers = emitNode.helpers;
+            if (helpers) {
+                return ts.orderedRemoveItem(helpers, helper);
+            }
+        }
+        return false;
+    }
+    ts.removeEmitHelper = removeEmitHelper;
+    /**
+     * Gets the EmitHelpers of a node.
+     */
+    function getEmitHelpers(node) {
+        var emitNode = node.emitNode;
+        return emitNode && emitNode.helpers;
+    }
+    ts.getEmitHelpers = getEmitHelpers;
+    /**
+     * Moves matching emit helpers from a source node to a target node.
+     */
+    function moveEmitHelpers(source, target, predicate) {
+        var sourceEmitNode = source.emitNode;
+        var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
+        if (!ts.some(sourceEmitHelpers))
+            return;
+        var targetEmitNode = getOrCreateEmitNode(target);
+        var helpersRemoved = 0;
+        for (var i = 0; i < sourceEmitHelpers.length; i++) {
+            var helper = sourceEmitHelpers[i];
+            if (predicate(helper)) {
+                helpersRemoved++;
+                targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper);
+            }
+            else if (helpersRemoved > 0) {
+                sourceEmitHelpers[i - helpersRemoved] = helper;
+            }
+        }
+        if (helpersRemoved > 0) {
+            sourceEmitHelpers.length -= helpersRemoved;
+        }
+    }
+    ts.moveEmitHelpers = moveEmitHelpers;
+    /* @internal */
+    function compareEmitHelpers(x, y) {
+        if (x === y)
+            return 0 /* EqualTo */;
+        if (x.priority === y.priority)
+            return 0 /* EqualTo */;
+        if (x.priority === undefined)
+            return 1 /* GreaterThan */;
+        if (y.priority === undefined)
+            return -1 /* LessThan */;
+        return ts.compareValues(x.priority, y.priority);
+    }
+    ts.compareEmitHelpers = compareEmitHelpers;
+    function setOriginalNode(node, original) {
+        node.original = original;
+        if (original) {
+            var emitNode = original.emitNode;
+            if (emitNode)
+                node.emitNode = mergeEmitNode(emitNode, node.emitNode);
+        }
+        return node;
+    }
+    ts.setOriginalNode = setOriginalNode;
+    function mergeEmitNode(sourceEmitNode, destEmitNode) {
+        var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers;
+        if (!destEmitNode)
+            destEmitNode = {};
+        // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
+        if (leadingComments)
+            destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments);
+        if (trailingComments)
+            destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments);
+        if (flags)
+            destEmitNode.flags = flags;
+        if (commentRange)
+            destEmitNode.commentRange = commentRange;
+        if (sourceMapRange)
+            destEmitNode.sourceMapRange = sourceMapRange;
+        if (tokenSourceMapRanges)
+            destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
+        if (constantValue !== undefined)
+            destEmitNode.constantValue = constantValue;
+        if (helpers)
+            destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers);
+        return destEmitNode;
+    }
+    function mergeTokenSourceMapRanges(sourceRanges, destRanges) {
+        if (!destRanges)
+            destRanges = [];
+        for (var key in sourceRanges) {
+            destRanges[key] = sourceRanges[key];
+        }
+        return destRanges;
+    }
+})(ts || (ts = {}));
+/* @internal */
+(function (ts) {
+    ts.nullTransformationContext = {
+        enableEmitNotification: ts.noop,
+        enableSubstitution: ts.noop,
+        endLexicalEnvironment: function () { return undefined; },
+        getCompilerOptions: ts.notImplemented,
+        getEmitHost: ts.notImplemented,
+        getEmitResolver: ts.notImplemented,
+        hoistFunctionDeclaration: ts.noop,
+        hoistVariableDeclaration: ts.noop,
+        isEmitNotificationEnabled: ts.notImplemented,
+        isSubstitutionEnabled: ts.notImplemented,
+        onEmitNode: ts.noop,
+        onSubstituteNode: ts.notImplemented,
+        readEmitHelpers: ts.notImplemented,
+        requestEmitHelper: ts.noop,
+        resumeLexicalEnvironment: ts.noop,
+        startLexicalEnvironment: ts.noop,
+        suspendLexicalEnvironment: ts.noop
+    };
+    function createTypeCheck(value, tag) {
+        return tag === "undefined"
+            ? ts.createStrictEquality(value, ts.createVoidZero())
+            : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag));
+    }
+    ts.createTypeCheck = createTypeCheck;
+    function createMemberAccessForPropertyName(target, memberName, location) {
+        if (ts.isComputedPropertyName(memberName)) {
+            return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location);
+        }
+        else {
+            var expression = ts.setTextRange(ts.isIdentifier(memberName)
+                ? ts.createPropertyAccess(target, memberName)
+                : ts.createElementAccess(target, memberName), memberName);
+            ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */;
+            return expression;
+        }
+    }
+    ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName;
+    function createFunctionCall(func, thisArg, argumentsList, location) {
+        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), 
+        /*typeArguments*/ undefined, [
+            thisArg
+        ].concat(argumentsList)), location);
+    }
+    ts.createFunctionCall = createFunctionCall;
+    function createFunctionApply(func, thisArg, argumentsExpression, location) {
+        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), 
+        /*typeArguments*/ undefined, [
+            thisArg,
+            argumentsExpression
+        ]), location);
+    }
+    ts.createFunctionApply = createFunctionApply;
+    function createArraySlice(array, start) {
+        var argumentsList = [];
+        if (start !== undefined) {
+            argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start);
+        }
+        return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
+    }
+    ts.createArraySlice = createArraySlice;
+    function createArrayConcat(array, values) {
+        return ts.createCall(ts.createPropertyAccess(array, "concat"), 
+        /*typeArguments*/ undefined, values);
+    }
+    ts.createArrayConcat = createArrayConcat;
+    function createMathPow(left, right, location) {
+        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), 
+        /*typeArguments*/ undefined, [left, right]), location);
+    }
+    ts.createMathPow = createMathPow;
+    function createReactNamespace(reactNamespace, parent) {
+        // To ensure the emit resolver can properly resolve the namespace, we need to
+        // treat this identifier as if it were a source tree node by clearing the `Synthesized`
+        // flag and setting a parent node.
+        var react = ts.createIdentifier(reactNamespace || "React");
+        react.flags &= ~8 /* Synthesized */;
+        // Set the parent that is in parse tree
+        // this makes sure that parent chain is intact for checker to traverse complete scope tree
+        react.parent = ts.getParseTreeNode(parent);
+        return react;
+    }
+    function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) {
+        if (ts.isQualifiedName(jsxFactory)) {
+            var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
+            var right = ts.createIdentifier(ts.idText(jsxFactory.right));
+            right.escapedText = jsxFactory.right.escapedText;
+            return ts.createPropertyAccess(left, right);
+        }
+        else {
+            return createReactNamespace(ts.idText(jsxFactory), parent);
+        }
+    }
+    function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) {
+        return jsxFactoryEntity ?
+            createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
+            ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement");
+    }
+    function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) {
+        var argumentsList = [tagName];
+        if (props) {
+            argumentsList.push(props);
+        }
+        if (children && children.length > 0) {
+            if (!props) {
+                argumentsList.push(ts.createNull());
+            }
+            if (children.length > 1) {
+                for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
+                    var child = children_1[_i];
+                    child.startsOnNewLine = true;
+                    argumentsList.push(child);
+                }
+            }
+            else {
+                argumentsList.push(children[0]);
+            }
+        }
+        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
+        /*typeArguments*/ undefined, argumentsList), location);
+    }
+    ts.createExpressionForJsxElement = createExpressionForJsxElement;
+    // Helpers
+    function getHelperName(name) {
+        return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */);
+    }
+    ts.getHelperName = getHelperName;
+    var valuesHelper = {
+        name: "typescript:values",
+        scoped: false,
+        text: "\n            var __values = (this && this.__values) || function (o) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\n                if (m) return m.call(o);\n                return {\n                    next: function () {\n                        if (o && i >= o.length) o = void 0;\n                        return { value: o && o[i++], done: !o };\n                    }\n                };\n            };\n        "
+    };
+    function createValuesHelper(context, expression, location) {
+        context.requestEmitHelper(valuesHelper);
+        return ts.setTextRange(ts.createCall(getHelperName("__values"), 
+        /*typeArguments*/ undefined, [expression]), location);
+    }
+    ts.createValuesHelper = createValuesHelper;
+    var readHelper = {
+        name: "typescript:read",
+        scoped: false,
+        text: "\n            var __read = (this && this.__read) || function (o, n) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n                if (!m) return o;\n                var i = m.call(o), r, ar = [], e;\n                try {\n                    while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n                }\n                catch (error) { e = { error: error }; }\n                finally {\n                    try {\n                        if (r && !r.done && (m = i[\"return\"])) m.call(i);\n                    }\n                    finally { if (e) throw e.error; }\n                }\n                return ar;\n            };\n        "
+    };
+    function createReadHelper(context, iteratorRecord, count, location) {
+        context.requestEmitHelper(readHelper);
+        return ts.setTextRange(ts.createCall(getHelperName("__read"), 
+        /*typeArguments*/ undefined, count !== undefined
+            ? [iteratorRecord, ts.createLiteral(count)]
+            : [iteratorRecord]), location);
+    }
+    ts.createReadHelper = createReadHelper;
+    var spreadHelper = {
+        name: "typescript:spread",
+        scoped: false,
+        text: "\n            var __spread = (this && this.__spread) || function () {\n                for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n                return ar;\n            };"
+    };
+    function createSpreadHelper(context, argumentList, location) {
+        context.requestEmitHelper(readHelper);
+        context.requestEmitHelper(spreadHelper);
+        return ts.setTextRange(ts.createCall(getHelperName("__spread"), 
+        /*typeArguments*/ undefined, argumentList), location);
+    }
+    ts.createSpreadHelper = createSpreadHelper;
+    // Utilities
+    function createForOfBindingStatement(node, boundValue) {
+        if (ts.isVariableDeclarationList(node)) {
+            var firstDeclaration = ts.firstOrUndefined(node.declarations);
+            var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, 
+            /*typeNode*/ undefined, boundValue);
+            return ts.setTextRange(ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), 
+            /*location*/ node);
+        }
+        else {
+            var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node);
+            return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node);
+        }
+    }
+    ts.createForOfBindingStatement = createForOfBindingStatement;
+    function insertLeadingStatement(dest, source) {
+        if (ts.isBlock(dest)) {
+            return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray([source].concat(dest.statements)), dest.statements));
+        }
+        else {
+            return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true);
+        }
+    }
+    ts.insertLeadingStatement = insertLeadingStatement;
+    function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) {
+        if (!outermostLabeledStatement) {
+            return node;
+        }
+        var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 222 /* LabeledStatement */
+            ? restoreEnclosingLabel(node, outermostLabeledStatement.statement)
+            : node);
+        if (afterRestoreLabelCallback) {
+            afterRestoreLabelCallback(outermostLabeledStatement);
+        }
+        return updated;
+    }
+    ts.restoreEnclosingLabel = restoreEnclosingLabel;
+    function shouldBeCapturedInTempVariable(node, cacheIdentifiers) {
+        var target = skipParentheses(node);
+        switch (target.kind) {
+            case 71 /* Identifier */:
+                return cacheIdentifiers;
+            case 99 /* ThisKeyword */:
+            case 8 /* NumericLiteral */:
+            case 9 /* StringLiteral */:
+                return false;
+            case 177 /* ArrayLiteralExpression */:
+                var elements = target.elements;
+                if (elements.length === 0) {
+                    return false;
+                }
+                return true;
+            case 178 /* ObjectLiteralExpression */:
+                return target.properties.length > 0;
+            default:
+                return true;
+        }
+    }
+    function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) {
+        var callee = skipOuterExpressions(expression, 7 /* All */);
+        var thisArg;
+        var target;
+        if (ts.isSuperProperty(callee)) {
+            thisArg = ts.createThis();
+            target = callee;
+        }
+        else if (callee.kind === 97 /* SuperKeyword */) {
+            thisArg = ts.createThis();
+            target = languageVersion < 2 /* ES2015 */
+                ? ts.setTextRange(ts.createIdentifier("_super"), callee)
+                : callee;
+        }
+        else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) {
+            thisArg = ts.createVoidZero();
+            target = parenthesizeForAccess(callee);
+        }
+        else {
+            switch (callee.kind) {
+                case 179 /* PropertyAccessExpression */: {
+                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
+                        // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
+                        thisArg = ts.createTempVariable(recordTempVariable);
+                        target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name);
+                        ts.setTextRange(target, callee);
+                    }
+                    else {
+                        thisArg = callee.expression;
+                        target = callee;
+                    }
+                    break;
+                }
+                case 180 /* ElementAccessExpression */: {
+                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
+                        // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
+                        thisArg = ts.createTempVariable(recordTempVariable);
+                        target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression);
+                        ts.setTextRange(target, callee);
+                    }
+                    else {
+                        thisArg = callee.expression;
+                        target = callee;
+                    }
+                    break;
+                }
+                default: {
+                    // for `a()` target is `a` and thisArg is `void 0`
+                    thisArg = ts.createVoidZero();
+                    target = parenthesizeForAccess(expression);
+                    break;
+                }
+            }
+        }
+        return { target: target, thisArg: thisArg };
+    }
+    ts.createCallBinding = createCallBinding;
+    function inlineExpressions(expressions) {
+        // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
+        // stack size exceeded" errors.
+        return expressions.length > 10
+            ? ts.createCommaList(expressions)
+            : ts.reduceLeft(expressions, ts.createComma);
+    }
+    ts.inlineExpressions = inlineExpressions;
+    function createExpressionFromEntityName(node) {
+        if (ts.isQualifiedName(node)) {
+            var left = createExpressionFromEntityName(node.left);
+            var right = ts.getMutableClone(node.right);
+            return ts.setTextRange(ts.createPropertyAccess(left, right), node);
+        }
+        else {
+            return ts.getMutableClone(node);
+        }
+    }
+    ts.createExpressionFromEntityName = createExpressionFromEntityName;
+    function createExpressionForPropertyName(memberName) {
+        if (ts.isIdentifier(memberName)) {
+            return ts.createLiteral(memberName);
+        }
+        else if (ts.isComputedPropertyName(memberName)) {
+            return ts.getMutableClone(memberName.expression);
+        }
+        else {
+            return ts.getMutableClone(memberName);
+        }
+    }
+    ts.createExpressionForPropertyName = createExpressionForPropertyName;
+    function createExpressionForObjectLiteralElementLike(node, property, receiver) {
+        switch (property.kind) {
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+                return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine);
+            case 261 /* PropertyAssignment */:
+                return createExpressionForPropertyAssignment(property, receiver);
+            case 262 /* ShorthandPropertyAssignment */:
+                return createExpressionForShorthandPropertyAssignment(property, receiver);
+            case 151 /* MethodDeclaration */:
+                return createExpressionForMethodDeclaration(property, receiver);
+        }
+    }
+    ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike;
+    function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) {
+        var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
+        if (property === firstAccessor) {
+            var properties_9 = [];
+            if (getAccessor) {
+                var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, getAccessor.parameters, 
+                /*type*/ undefined, getAccessor.body);
+                ts.setTextRange(getterFunction, getAccessor);
+                ts.setOriginalNode(getterFunction, getAccessor);
+                var getter = ts.createPropertyAssignment("get", getterFunction);
+                properties_9.push(getter);
+            }
+            if (setAccessor) {
+                var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, setAccessor.parameters, 
+                /*type*/ undefined, setAccessor.body);
+                ts.setTextRange(setterFunction, setAccessor);
+                ts.setOriginalNode(setterFunction, setAccessor);
+                var setter = ts.createPropertyAssignment("set", setterFunction);
+                properties_9.push(setter);
+            }
+            properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue()));
+            properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue()));
+            var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
+            /*typeArguments*/ undefined, [
+                receiver,
+                createExpressionForPropertyName(property.name),
+                ts.createObjectLiteral(properties_9, multiLine)
+            ]), 
+            /*location*/ firstAccessor);
+            return ts.aggregateTransformFlags(expression);
+        }
+        return undefined;
+    }
+    function createExpressionForPropertyAssignment(property, receiver) {
+        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property));
+    }
+    function createExpressionForShorthandPropertyAssignment(property, receiver) {
+        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), 
+        /*location*/ property), 
+        /*original*/ property));
+    }
+    function createExpressionForMethodDeclaration(method, receiver) {
+        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, 
+        /*name*/ undefined, 
+        /*typeParameters*/ undefined, method.parameters, 
+        /*type*/ undefined, method.body), 
+        /*location*/ method), 
+        /*original*/ method)), 
+        /*location*/ method), 
+        /*original*/ method));
+    }
+    /**
+     * Gets the internal name of a declaration. This is primarily used for declarations that can be
+     * referred to by name in the body of an ES5 class function body. An internal name will *never*
+     * be prefixed with an module or namespace export modifier like "exports." when emitted as an
+     * expression. An internal name will also *never* be renamed due to a collision with a block
+     * scoped variable.
+     *
+     * @param node The declaration.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getInternalName(node, allowComments, allowSourceMaps) {
+        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */);
+    }
+    ts.getInternalName = getInternalName;
+    /**
+     * Gets whether an identifier should only be referred to by its internal name.
+     */
+    function isInternalName(node) {
+        return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0;
+    }
+    ts.isInternalName = isInternalName;
+    /**
+     * Gets the local name of a declaration. This is primarily used for declarations that can be
+     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
+     * local name will *never* be prefixed with an module or namespace export modifier like
+     * "exports." when emitted as an expression.
+     *
+     * @param node The declaration.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getLocalName(node, allowComments, allowSourceMaps) {
+        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */);
+    }
+    ts.getLocalName = getLocalName;
+    /**
+     * Gets whether an identifier should only be referred to by its local name.
+     */
+    function isLocalName(node) {
+        return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0;
+    }
+    ts.isLocalName = isLocalName;
+    /**
+     * Gets the export name of a declaration. This is primarily used for declarations that can be
+     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
+     * export name will *always* be prefixed with an module or namespace export modifier like
+     * `"exports."` when emitted as an expression if the name points to an exported symbol.
+     *
+     * @param node The declaration.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getExportName(node, allowComments, allowSourceMaps) {
+        return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */);
+    }
+    ts.getExportName = getExportName;
+    /**
+     * Gets whether an identifier should only be referred to by its export representation if the
+     * name points to an exported symbol.
+     */
+    function isExportName(node) {
+        return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0;
+    }
+    ts.isExportName = isExportName;
+    /**
+     * Gets the name of a declaration for use in declarations.
+     *
+     * @param node The declaration.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getDeclarationName(node, allowComments, allowSourceMaps) {
+        return getName(node, allowComments, allowSourceMaps);
+    }
+    ts.getDeclarationName = getDeclarationName;
+    function getName(node, allowComments, allowSourceMaps, emitFlags) {
+        var nodeName = ts.getNameOfDeclaration(node);
+        if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) {
+            var name = ts.getMutableClone(nodeName);
+            emitFlags |= ts.getEmitFlags(nodeName);
+            if (!allowSourceMaps)
+                emitFlags |= 48 /* NoSourceMap */;
+            if (!allowComments)
+                emitFlags |= 1536 /* NoComments */;
+            if (emitFlags)
+                ts.setEmitFlags(name, emitFlags);
+            return name;
+        }
+        return ts.getGeneratedNameForNode(node);
+    }
+    /**
+     * Gets the exported name of a declaration for use in expressions.
+     *
+     * An exported name will *always* be prefixed with an module or namespace export modifier like
+     * "exports." if the name points to an exported symbol.
+     *
+     * @param ns The namespace identifier.
+     * @param node The declaration.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) {
+        if (ns && ts.hasModifier(node, 1 /* Export */)) {
+            return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
+        }
+        return getExportName(node, allowComments, allowSourceMaps);
+    }
+    ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName;
+    /**
+     * Gets a namespace-qualified name for use in expressions.
+     *
+     * @param ns The namespace identifier.
+     * @param name The name.
+     * @param allowComments A value indicating whether comments may be emitted for the name.
+     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
+     */
+    function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) {
+        var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name));
+        ts.setTextRange(qualifiedName, name);
+        var emitFlags;
+        if (!allowSourceMaps)
+            emitFlags |= 48 /* NoSourceMap */;
+        if (!allowComments)
+            emitFlags |= 1536 /* NoComments */;
+        if (emitFlags)
+            ts.setEmitFlags(qualifiedName, emitFlags);
+        return qualifiedName;
+    }
+    ts.getNamespaceMemberName = getNamespaceMemberName;
+    function convertToFunctionBody(node, multiLine) {
+        return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node);
+    }
+    ts.convertToFunctionBody = convertToFunctionBody;
+    function convertFunctionDeclarationToExpression(node) {
+        ts.Debug.assert(!!node.body);
+        var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
+        ts.setOriginalNode(updated, node);
+        ts.setTextRange(updated, node);
+        if (node.startsOnNewLine) {
+            updated.startsOnNewLine = true;
+        }
+        ts.aggregateTransformFlags(updated);
+        return updated;
+    }
+    ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression;
+    function isUseStrictPrologue(node) {
+        return ts.isStringLiteral(node.expression) && node.expression.text === "use strict";
+    }
+    /**
+     * Add any necessary prologue-directives into target statement-array.
+     * The function needs to be called during each transformation step.
+     * This function needs to be called whenever we transform the statement
+     * list of a source file, namespace, or function-like body.
+     *
+     * @param target: result statements array
+     * @param source: origin statements array
+     * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
+     * @param visitor: Optional callback used to visit any custom prologue directives.
+     */
+    function addPrologue(target, source, ensureUseStrict, visitor) {
+        var offset = addStandardPrologue(target, source, ensureUseStrict);
+        return addCustomPrologue(target, source, offset, visitor);
+    }
+    ts.addPrologue = addPrologue;
+    /**
+     * Add just the standard (string-expression) prologue-directives into target statement-array.
+     * The function needs to be called during each transformation step.
+     * This function needs to be called whenever we transform the statement
+     * list of a source file, namespace, or function-like body.
+     */
+    function addStandardPrologue(target, source, ensureUseStrict) {
+        ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
+        var foundUseStrict = false;
+        var statementOffset = 0;
+        var numStatements = source.length;
+        while (statementOffset < numStatements) {
+            var statement = source[statementOffset];
+            if (ts.isPrologueDirective(statement)) {
+                if (isUseStrictPrologue(statement)) {
+                    foundUseStrict = true;
+                }
+                target.push(statement);
+            }
+            else {
+                break;
+            }
+            statementOffset++;
+        }
+        if (ensureUseStrict && !foundUseStrict) {
+            target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))));
+        }
+        return statementOffset;
+    }
+    ts.addStandardPrologue = addStandardPrologue;
+    /**
+     * Add just the custom prologue-directives into target statement-array.
+     * The function needs to be called during each transformation step.
+     * This function needs to be called whenever we transform the statement
+     * list of a source file, namespace, or function-like body.
+     */
+    function addCustomPrologue(target, source, statementOffset, visitor) {
+        var numStatements = source.length;
+        while (statementOffset < numStatements) {
+            var statement = source[statementOffset];
+            if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */) {
+                target.push(visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement);
+            }
+            else {
+                break;
+            }
+            statementOffset++;
+        }
+        return statementOffset;
+    }
+    ts.addCustomPrologue = addCustomPrologue;
+    function startsWithUseStrict(statements) {
+        var firstStatement = ts.firstOrUndefined(statements);
+        return firstStatement !== undefined
+            && ts.isPrologueDirective(firstStatement)
+            && isUseStrictPrologue(firstStatement);
+    }
+    ts.startsWithUseStrict = startsWithUseStrict;
+    /**
+     * Ensures "use strict" directive is added
+     *
+     * @param statements An array of statements
+     */
+    function ensureUseStrict(statements) {
+        var foundUseStrict = false;
+        for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) {
+            var statement = statements_3[_i];
+            if (ts.isPrologueDirective(statement)) {
+                if (isUseStrictPrologue(statement)) {
+                    foundUseStrict = true;
+                    break;
+                }
+            }
+            else {
+                break;
+            }
+        }
+        if (!foundUseStrict) {
+            return ts.setTextRange(ts.createNodeArray([
+                startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))
+            ].concat(statements)), statements);
+        }
+        return statements;
+    }
+    ts.ensureUseStrict = ensureUseStrict;
+    /**
+     * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
+     * order of operations.
+     *
+     * @param binaryOperator The operator for the BinaryExpression.
+     * @param operand The operand for the BinaryExpression.
+     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
+     *                           BinaryExpression.
+     */
+    function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
+        var skipped = ts.skipPartiallyEmittedExpressions(operand);
+        // If the resulting expression is already parenthesized, we do not need to do any further processing.
+        if (skipped.kind === 185 /* ParenthesizedExpression */) {
+            return operand;
+        }
+        return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand)
+            ? ts.createParen(operand)
+            : operand;
+    }
+    ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand;
+    /**
+     * Determines whether the operand to a BinaryExpression needs to be parenthesized.
+     *
+     * @param binaryOperator The operator for the BinaryExpression.
+     * @param operand The operand for the BinaryExpression.
+     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
+     *                           BinaryExpression.
+     */
+    function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
+        // If the operand has lower precedence, then it needs to be parenthesized to preserve the
+        // intent of the expression. For example, if the operand is `a + b` and the operator is
+        // `*`, then we need to parenthesize the operand to preserve the intended order of
+        // operations: `(a + b) * x`.
+        //
+        // If the operand has higher precedence, then it does not need to be parenthesized. For
+        // example, if the operand is `a * b` and the operator is `+`, then we do not need to
+        // parenthesize to preserve the intended order of operations: `a * b + x`.
+        //
+        // If the operand has the same precedence, then we need to check the associativity of
+        // the operator based on whether this is the left or right operand of the expression.
+        //
+        // For example, if `a / d` is on the right of operator `*`, we need to parenthesize
+        // to preserve the intended order of operations: `x * (a / d)`
+        //
+        // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve
+        // the intended order of operations: `(a ** b) ** c`
+        var binaryOperatorPrecedence = ts.getOperatorPrecedence(194 /* BinaryExpression */, binaryOperator);
+        var binaryOperatorAssociativity = ts.getOperatorAssociativity(194 /* BinaryExpression */, binaryOperator);
+        var emittedOperand = ts.skipPartiallyEmittedExpressions(operand);
+        var operandPrecedence = ts.getExpressionPrecedence(emittedOperand);
+        switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) {
+            case -1 /* LessThan */:
+                // If the operand is the right side of a right-associative binary operation
+                // and is a yield expression, then we do not need parentheses.
+                if (!isLeftSideOfBinary
+                    && binaryOperatorAssociativity === 1 /* Right */
+                    && operand.kind === 197 /* YieldExpression */) {
+                    return false;
+                }
+                return true;
+            case 1 /* GreaterThan */:
+                return false;
+            case 0 /* EqualTo */:
+                if (isLeftSideOfBinary) {
+                    // No need to parenthesize the left operand when the binary operator is
+                    // left associative:
+                    //  (a*b)/x    ->  a*b/x
+                    //  (a**b)/x   ->  a**b/x
+                    //
+                    // Parentheses are needed for the left operand when the binary operator is
+                    // right associative:
+                    //  (a/b)**x   ->  (a/b)**x
+                    //  (a**b)**x  ->  (a**b)**x
+                    return binaryOperatorAssociativity === 1 /* Right */;
+                }
+                else {
+                    if (ts.isBinaryExpression(emittedOperand)
+                        && emittedOperand.operatorToken.kind === binaryOperator) {
+                        // No need to parenthesize the right operand when the binary operator and
+                        // operand are the same and one of the following:
+                        //  x*(a*b)     => x*a*b
+                        //  x|(a|b)     => x|a|b
+                        //  x&(a&b)     => x&a&b
+                        //  x^(a^b)     => x^a^b
+                        if (operatorHasAssociativeProperty(binaryOperator)) {
+                            return false;
+                        }
+                        // No need to parenthesize the right operand when the binary operator
+                        // is plus (+) if both the left and right operands consist solely of either
+                        // literals of the same kind or binary plus (+) expressions for literals of
+                        // the same kind (recursively).
+                        //  "a"+(1+2)       => "a"+(1+2)
+                        //  "a"+("b"+"c")   => "a"+"b"+"c"
+                        if (binaryOperator === 37 /* PlusToken */) {
+                            var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */;
+                            if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) {
+                                return false;
+                            }
+                        }
+                    }
+                    // No need to parenthesize the right operand when the operand is right
+                    // associative:
+                    //  x/(a**b)    -> x/a**b
+                    //  x**(a**b)   -> x**a**b
+                    //
+                    // Parentheses are needed for the right operand when the operand is left
+                    // associative:
+                    //  x/(a*b)     -> x/(a*b)
+                    //  x**(a/b)    -> x**(a/b)
+                    var operandAssociativity = ts.getExpressionAssociativity(emittedOperand);
+                    return operandAssociativity === 0 /* Left */;
+                }
+        }
+    }
+    /**
+     * Determines whether a binary operator is mathematically associative.
+     *
+     * @param binaryOperator The binary operator.
+     */
+    function operatorHasAssociativeProperty(binaryOperator) {
+        // The following operators are associative in JavaScript:
+        //  (a*b)*c     -> a*(b*c)  -> a*b*c
+        //  (a|b)|c     -> a|(b|c)  -> a|b|c
+        //  (a&b)&c     -> a&(b&c)  -> a&b&c
+        //  (a^b)^c     -> a^(b^c)  -> a^b^c
+        //
+        // While addition is associative in mathematics, JavaScript's `+` is not
+        // guaranteed to be associative as it is overloaded with string concatenation.
+        return binaryOperator === 39 /* AsteriskToken */
+            || binaryOperator === 49 /* BarToken */
+            || binaryOperator === 48 /* AmpersandToken */
+            || binaryOperator === 50 /* CaretToken */;
+    }
+    /**
+     * This function determines whether an expression consists of a homogeneous set of
+     * literal expressions or binary plus expressions that all share the same literal kind.
+     * It is used to determine whether the right-hand operand of a binary plus expression can be
+     * emitted without parentheses.
+     */
+    function getLiteralKindOfBinaryPlusOperand(node) {
+        node = ts.skipPartiallyEmittedExpressions(node);
+        if (ts.isLiteralKind(node.kind)) {
+            return node.kind;
+        }
+        if (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 37 /* PlusToken */) {
+            if (node.cachedLiteralKind !== undefined) {
+                return node.cachedLiteralKind;
+            }
+            var leftKind = getLiteralKindOfBinaryPlusOperand(node.left);
+            var literalKind = ts.isLiteralKind(leftKind)
+                && leftKind === getLiteralKindOfBinaryPlusOperand(node.right)
+                ? leftKind
+                : 0 /* Unknown */;
+            node.cachedLiteralKind = literalKind;
+            return literalKind;
+        }
+        return 0 /* Unknown */;
+    }
+    function parenthesizeForConditionalHead(condition) {
+        var conditionalPrecedence = ts.getOperatorPrecedence(195 /* ConditionalExpression */, 55 /* QuestionToken */);
+        var emittedCondition = ts.skipPartiallyEmittedExpressions(condition);
+        var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition);
+        if (ts.compareValues(conditionPrecedence, conditionalPrecedence) === -1 /* LessThan */) {
+            return ts.createParen(condition);
+        }
+        return condition;
+    }
+    ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead;
+    function parenthesizeSubexpressionOfConditionalExpression(e) {
+        // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
+        // so in case when comma expression is introduced as a part of previous transformations
+        // if should be wrapped in parens since comma operator has the lowest precedence
+        return e.kind === 194 /* BinaryExpression */ && e.operatorToken.kind === 26 /* CommaToken */
+            ? ts.createParen(e)
+            : e;
+    }
+    ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression;
+    /**
+     * Wraps an expression in parentheses if it is needed in order to use the expression
+     * as the expression of a NewExpression node.
+     *
+     * @param expression The Expression node.
+     */
+    function parenthesizeForNew(expression) {
+        var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true);
+        switch (leftmostExpr.kind) {
+            case 181 /* CallExpression */:
+                return ts.createParen(expression);
+            case 182 /* NewExpression */:
+                return !leftmostExpr.arguments
+                    ? ts.createParen(expression)
+                    : expression;
+        }
+        return parenthesizeForAccess(expression);
+    }
+    ts.parenthesizeForNew = parenthesizeForNew;
+    /**
+     * Wraps an expression in parentheses if it is needed in order to use the expression for
+     * property or element access.
+     *
+     * @param expr The expression node.
+     */
+    function parenthesizeForAccess(expression) {
+        // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
+        // to parenthesize the expression before a dot. The known exception is:
+        //
+        //    NewExpression:
+        //       new C.x        -> not the same as (new C).x
+        //
+        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
+        if (ts.isLeftHandSideExpression(emittedExpression)
+            && (emittedExpression.kind !== 182 /* NewExpression */ || emittedExpression.arguments)) {
+            return expression;
+        }
+        return ts.setTextRange(ts.createParen(expression), expression);
+    }
+    ts.parenthesizeForAccess = parenthesizeForAccess;
+    function parenthesizePostfixOperand(operand) {
+        return ts.isLeftHandSideExpression(operand)
+            ? operand
+            : ts.setTextRange(ts.createParen(operand), operand);
+    }
+    ts.parenthesizePostfixOperand = parenthesizePostfixOperand;
+    function parenthesizePrefixOperand(operand) {
+        return ts.isUnaryExpression(operand)
+            ? operand
+            : ts.setTextRange(ts.createParen(operand), operand);
+    }
+    ts.parenthesizePrefixOperand = parenthesizePrefixOperand;
+    function parenthesizeListElements(elements) {
+        var result;
+        for (var i = 0; i < elements.length; i++) {
+            var element = parenthesizeExpressionForList(elements[i]);
+            if (result !== undefined || element !== elements[i]) {
+                if (result === undefined) {
+                    result = elements.slice(0, i);
+                }
+                result.push(element);
+            }
+        }
+        if (result !== undefined) {
+            return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements);
+        }
+        return elements;
+    }
+    ts.parenthesizeListElements = parenthesizeListElements;
+    function parenthesizeExpressionForList(expression) {
+        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
+        var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression);
+        var commaPrecedence = ts.getOperatorPrecedence(194 /* BinaryExpression */, 26 /* CommaToken */);
+        return expressionPrecedence > commaPrecedence
+            ? expression
+            : ts.setTextRange(ts.createParen(expression), expression);
+    }
+    ts.parenthesizeExpressionForList = parenthesizeExpressionForList;
+    function parenthesizeExpressionForExpressionStatement(expression) {
+        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
+        if (ts.isCallExpression(emittedExpression)) {
+            var callee = emittedExpression.expression;
+            var kind = ts.skipPartiallyEmittedExpressions(callee).kind;
+            if (kind === 186 /* FunctionExpression */ || kind === 187 /* ArrowFunction */) {
+                var mutableCall = ts.getMutableClone(emittedExpression);
+                mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee);
+                return recreateOuterExpressions(expression, mutableCall, 4 /* PartiallyEmittedExpressions */);
+            }
+        }
+        var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind;
+        if (leftmostExpressionKind === 178 /* ObjectLiteralExpression */ || leftmostExpressionKind === 186 /* FunctionExpression */) {
+            return ts.setTextRange(ts.createParen(expression), expression);
+        }
+        return expression;
+    }
+    ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement;
+    function parenthesizeElementTypeMember(member) {
+        switch (member.kind) {
+            case 166 /* UnionType */:
+            case 167 /* IntersectionType */:
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+                return ts.createParenthesizedType(member);
+        }
+        return member;
+    }
+    ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember;
+    function parenthesizeArrayTypeMember(member) {
+        switch (member.kind) {
+            case 162 /* TypeQuery */:
+            case 170 /* TypeOperator */:
+                return ts.createParenthesizedType(member);
+        }
+        return parenthesizeElementTypeMember(member);
+    }
+    ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember;
+    function parenthesizeElementTypeMembers(members) {
+        return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember));
+    }
+    ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers;
+    function parenthesizeTypeParameters(typeParameters) {
+        if (ts.some(typeParameters)) {
+            var params = [];
+            for (var i = 0; i < typeParameters.length; ++i) {
+                var entry = typeParameters[i];
+                params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
+                    ts.createParenthesizedType(entry) :
+                    entry);
+            }
+            return ts.createNodeArray(params);
+        }
+    }
+    ts.parenthesizeTypeParameters = parenthesizeTypeParameters;
+    function getLeftmostExpression(node, stopAtCallExpressions) {
+        while (true) {
+            switch (node.kind) {
+                case 193 /* PostfixUnaryExpression */:
+                    node = node.operand;
+                    continue;
+                case 194 /* BinaryExpression */:
+                    node = node.left;
+                    continue;
+                case 195 /* ConditionalExpression */:
+                    node = node.condition;
+                    continue;
+                case 181 /* CallExpression */:
+                    if (stopAtCallExpressions) {
+                        return node;
+                    }
+                // falls through
+                case 180 /* ElementAccessExpression */:
+                case 179 /* PropertyAccessExpression */:
+                    node = node.expression;
+                    continue;
+                case 288 /* PartiallyEmittedExpression */:
+                    node = node.expression;
+                    continue;
+            }
+            return node;
+        }
+    }
+    function parenthesizeConciseBody(body) {
+        if (!ts.isBlock(body) && getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 178 /* ObjectLiteralExpression */) {
+            return ts.setTextRange(ts.createParen(body), body);
+        }
+        return body;
+    }
+    ts.parenthesizeConciseBody = parenthesizeConciseBody;
+    var OuterExpressionKinds;
+    (function (OuterExpressionKinds) {
+        OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses";
+        OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 2] = "Assertions";
+        OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 4] = "PartiallyEmittedExpressions";
+        OuterExpressionKinds[OuterExpressionKinds["All"] = 7] = "All";
+    })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {}));
+    function isOuterExpression(node, kinds) {
+        if (kinds === void 0) { kinds = 7 /* All */; }
+        switch (node.kind) {
+            case 185 /* ParenthesizedExpression */:
+                return (kinds & 1 /* Parentheses */) !== 0;
+            case 184 /* TypeAssertionExpression */:
+            case 202 /* AsExpression */:
+            case 203 /* NonNullExpression */:
+                return (kinds & 2 /* Assertions */) !== 0;
+            case 288 /* PartiallyEmittedExpression */:
+                return (kinds & 4 /* PartiallyEmittedExpressions */) !== 0;
+        }
+        return false;
+    }
+    ts.isOuterExpression = isOuterExpression;
+    function skipOuterExpressions(node, kinds) {
+        if (kinds === void 0) { kinds = 7 /* All */; }
+        var previousNode;
+        do {
+            previousNode = node;
+            if (kinds & 1 /* Parentheses */) {
+                node = skipParentheses(node);
+            }
+            if (kinds & 2 /* Assertions */) {
+                node = skipAssertions(node);
+            }
+            if (kinds & 4 /* PartiallyEmittedExpressions */) {
+                node = ts.skipPartiallyEmittedExpressions(node);
+            }
+        } while (previousNode !== node);
+        return node;
+    }
+    ts.skipOuterExpressions = skipOuterExpressions;
+    function skipParentheses(node) {
+        while (node.kind === 185 /* ParenthesizedExpression */) {
+            node = node.expression;
+        }
+        return node;
+    }
+    ts.skipParentheses = skipParentheses;
+    function skipAssertions(node) {
+        while (ts.isAssertionExpression(node) || node.kind === 203 /* NonNullExpression */) {
+            node = node.expression;
+        }
+        return node;
+    }
+    ts.skipAssertions = skipAssertions;
+    function updateOuterExpression(outerExpression, expression) {
+        switch (outerExpression.kind) {
+            case 185 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression);
+            case 184 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression);
+            case 202 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type);
+            case 203 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression);
+            case 288 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
+        }
+    }
+    /**
+     * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
+     *
+     * A parenthesized expression can be ignored when all of the following are true:
+     *
+     * - It's `pos` and `end` are not -1
+     * - It does not have a custom source map range
+     * - It does not have a custom comment range
+     * - It does not have synthetic leading or trailing comments
+     *
+     * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
+     * the expression to maintain precedence, a new parenthesized expression should be created automatically when
+     * the containing expression is created/updated.
+     */
+    function isIgnorableParen(node) {
+        return node.kind === 185 /* ParenthesizedExpression */
+            && ts.nodeIsSynthesized(node)
+            && ts.nodeIsSynthesized(ts.getSourceMapRange(node))
+            && ts.nodeIsSynthesized(ts.getCommentRange(node))
+            && !ts.some(ts.getSyntheticLeadingComments(node))
+            && !ts.some(ts.getSyntheticTrailingComments(node));
+    }
+    function recreateOuterExpressions(outerExpression, innerExpression, kinds) {
+        if (kinds === void 0) { kinds = 7 /* All */; }
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
+            return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
+        }
+        return innerExpression;
+    }
+    ts.recreateOuterExpressions = recreateOuterExpressions;
+    function startOnNewLine(node) {
+        node.startsOnNewLine = true;
+        return node;
+    }
+    ts.startOnNewLine = startOnNewLine;
+    function getExternalHelpersModuleName(node) {
+        var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
+        var emitNode = parseNode && parseNode.emitNode;
+        return emitNode && emitNode.externalHelpersModuleName;
+    }
+    ts.getExternalHelpersModuleName = getExternalHelpersModuleName;
+    function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues) {
+        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) {
+            var externalHelpersModuleName = getExternalHelpersModuleName(node);
+            if (externalHelpersModuleName) {
+                return externalHelpersModuleName;
+            }
+            var moduleKind = ts.getEmitModuleKind(compilerOptions);
+            var create = hasExportStarsToExportValues
+                && moduleKind !== ts.ModuleKind.System
+                && moduleKind !== ts.ModuleKind.ES2015
+                && moduleKind !== ts.ModuleKind.ESNext;
+            if (!create) {
+                var helpers = ts.getEmitHelpers(node);
+                if (helpers) {
+                    for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) {
+                        var helper = helpers_2[_i];
+                        if (!helper.scoped) {
+                            create = true;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (create) {
+                var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
+                var emitNode = ts.getOrCreateEmitNode(parseNode);
+                return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText));
+            }
+        }
+    }
+    ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded;
+    /**
+     * Get the name of that target module from an import or export declaration
+     */
+    function getLocalNameForExternalImport(node, sourceFile) {
+        var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
+        if (namespaceDeclaration && !ts.isDefaultImport(node)) {
+            var name = namespaceDeclaration.name;
+            return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name));
+        }
+        if (node.kind === 238 /* ImportDeclaration */ && node.importClause) {
+            return ts.getGeneratedNameForNode(node);
+        }
+        if (node.kind === 244 /* ExportDeclaration */ && node.moduleSpecifier) {
+            return ts.getGeneratedNameForNode(node);
+        }
+        return undefined;
+    }
+    ts.getLocalNameForExternalImport = getLocalNameForExternalImport;
+    /**
+     * Get the name of a target module from an import/export declaration as should be written in the emitted output.
+     * The emitted output name can be different from the input if:
+     *  1. The module has a /// <amd-module name="<new name>" />
+     *  2. --out or --outFile is used, making the name relative to the rootDir
+     *  3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
+     * Otherwise, a new StringLiteral node representing the module name will be returned.
+     */
+    function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) {
+        var moduleName = ts.getExternalModuleName(importNode);
+        if (moduleName.kind === 9 /* StringLiteral */) {
+            return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
+                || tryRenameExternalModule(moduleName, sourceFile)
+                || ts.getSynthesizedClone(moduleName);
+        }
+        return undefined;
+    }
+    ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral;
+    /**
+     * Some bundlers (SystemJS builder) sometimes want to rename dependencies.
+     * Here we check if alternative name was provided for a given moduleName and return it if possible.
+     */
+    function tryRenameExternalModule(moduleName, sourceFile) {
+        var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
+        return rename && ts.createLiteral(rename);
+    }
+    /**
+     * Get the name of a module as should be written in the emitted output.
+     * The emitted output name can be different from the input if:
+     *  1. The module has a /// <amd-module name="<new name>" />
+     *  2. --out or --outFile is used, making the name relative to the rootDir
+     * Otherwise, a new StringLiteral node representing the module name will be returned.
+     */
+    function tryGetModuleNameFromFile(file, host, options) {
+        if (!file) {
+            return undefined;
+        }
+        if (file.moduleName) {
+            return ts.createLiteral(file.moduleName);
+        }
+        if (!file.isDeclarationFile && (options.out || options.outFile)) {
+            return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName));
+        }
+        return undefined;
+    }
+    ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile;
+    function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) {
+        return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
+    }
+    /**
+     * Gets the initializer of an BindingOrAssignmentElement.
+     */
+    function getInitializerOfBindingOrAssignmentElement(bindingElement) {
+        if (ts.isDeclarationBindingElement(bindingElement)) {
+            // `1` in `let { a = 1 } = ...`
+            // `1` in `let { a: b = 1 } = ...`
+            // `1` in `let { a: {b} = 1 } = ...`
+            // `1` in `let { a: [b] = 1 } = ...`
+            // `1` in `let [a = 1] = ...`
+            // `1` in `let [{a} = 1] = ...`
+            // `1` in `let [[a] = 1] = ...`
+            return bindingElement.initializer;
+        }
+        if (ts.isPropertyAssignment(bindingElement)) {
+            // `1` in `({ a: b = 1 } = ...)`
+            // `1` in `({ a: {b} = 1 } = ...)`
+            // `1` in `({ a: [b] = 1 } = ...)`
+            return ts.isAssignmentExpression(bindingElement.initializer, /*excludeCompoundAssignment*/ true)
+                ? bindingElement.initializer.right
+                : undefined;
+        }
+        if (ts.isShorthandPropertyAssignment(bindingElement)) {
+            // `1` in `({ a = 1 } = ...)`
+            return bindingElement.objectAssignmentInitializer;
+        }
+        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
+            // `1` in `[a = 1] = ...`
+            // `1` in `[{a} = 1] = ...`
+            // `1` in `[[a] = 1] = ...`
+            return bindingElement.right;
+        }
+        if (ts.isSpreadElement(bindingElement)) {
+            // Recovery consistent with existing emit.
+            return getInitializerOfBindingOrAssignmentElement(bindingElement.expression);
+        }
+    }
+    ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement;
+    /**
+     * Gets the name of an BindingOrAssignmentElement.
+     */
+    function getTargetOfBindingOrAssignmentElement(bindingElement) {
+        if (ts.isDeclarationBindingElement(bindingElement)) {
+            // `a` in `let { a } = ...`
+            // `a` in `let { a = 1 } = ...`
+            // `b` in `let { a: b } = ...`
+            // `b` in `let { a: b = 1 } = ...`
+            // `a` in `let { ...a } = ...`
+            // `{b}` in `let { a: {b} } = ...`
+            // `{b}` in `let { a: {b} = 1 } = ...`
+            // `[b]` in `let { a: [b] } = ...`
+            // `[b]` in `let { a: [b] = 1 } = ...`
+            // `a` in `let [a] = ...`
+            // `a` in `let [a = 1] = ...`
+            // `a` in `let [...a] = ...`
+            // `{a}` in `let [{a}] = ...`
+            // `{a}` in `let [{a} = 1] = ...`
+            // `[a]` in `let [[a]] = ...`
+            // `[a]` in `let [[a] = 1] = ...`
+            return bindingElement.name;
+        }
+        if (ts.isObjectLiteralElementLike(bindingElement)) {
+            switch (bindingElement.kind) {
+                case 261 /* PropertyAssignment */:
+                    // `b` in `({ a: b } = ...)`
+                    // `b` in `({ a: b = 1 } = ...)`
+                    // `{b}` in `({ a: {b} } = ...)`
+                    // `{b}` in `({ a: {b} = 1 } = ...)`
+                    // `[b]` in `({ a: [b] } = ...)`
+                    // `[b]` in `({ a: [b] = 1 } = ...)`
+                    // `b.c` in `({ a: b.c } = ...)`
+                    // `b.c` in `({ a: b.c = 1 } = ...)`
+                    // `b[0]` in `({ a: b[0] } = ...)`
+                    // `b[0]` in `({ a: b[0] = 1 } = ...)`
+                    return getTargetOfBindingOrAssignmentElement(bindingElement.initializer);
+                case 262 /* ShorthandPropertyAssignment */:
+                    // `a` in `({ a } = ...)`
+                    // `a` in `({ a = 1 } = ...)`
+                    return bindingElement.name;
+                case 263 /* SpreadAssignment */:
+                    // `a` in `({ ...a } = ...)`
+                    return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
+            }
+            // no target
+            return undefined;
+        }
+        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
+            // `a` in `[a = 1] = ...`
+            // `{a}` in `[{a} = 1] = ...`
+            // `[a]` in `[[a] = 1] = ...`
+            // `a.b` in `[a.b = 1] = ...`
+            // `a[0]` in `[a[0] = 1] = ...`
+            return getTargetOfBindingOrAssignmentElement(bindingElement.left);
+        }
+        if (ts.isSpreadElement(bindingElement)) {
+            // `a` in `[...a] = ...`
+            return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
+        }
+        // `a` in `[a] = ...`
+        // `{a}` in `[{a}] = ...`
+        // `[a]` in `[[a]] = ...`
+        // `a.b` in `[a.b] = ...`
+        // `a[0]` in `[a[0]] = ...`
+        return bindingElement;
+    }
+    ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement;
+    /**
+     * Determines whether an BindingOrAssignmentElement is a rest element.
+     */
+    function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) {
+        switch (bindingElement.kind) {
+            case 146 /* Parameter */:
+            case 176 /* BindingElement */:
+                // `...` in `let [...a] = ...`
+                return bindingElement.dotDotDotToken;
+            case 198 /* SpreadElement */:
+            case 263 /* SpreadAssignment */:
+                // `...` in `[...a] = ...`
+                return bindingElement;
+        }
+        return undefined;
+    }
+    ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement;
+    /**
+     * Gets the property name of a BindingOrAssignmentElement
+     */
+    function getPropertyNameOfBindingOrAssignmentElement(bindingElement) {
+        switch (bindingElement.kind) {
+            case 176 /* BindingElement */:
+                // `a` in `let { a: b } = ...`
+                // `[a]` in `let { [a]: b } = ...`
+                // `"a"` in `let { "a": b } = ...`
+                // `1` in `let { 1: b } = ...`
+                if (bindingElement.propertyName) {
+                    var propertyName = bindingElement.propertyName;
+                    return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression)
+                        ? propertyName.expression
+                        : propertyName;
+                }
+                break;
+            case 261 /* PropertyAssignment */:
+                // `a` in `({ a: b } = ...)`
+                // `[a]` in `({ [a]: b } = ...)`
+                // `"a"` in `({ "a": b } = ...)`
+                // `1` in `({ 1: b } = ...)`
+                if (bindingElement.name) {
+                    var propertyName = bindingElement.name;
+                    return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression)
+                        ? propertyName.expression
+                        : propertyName;
+                }
+                break;
+            case 263 /* SpreadAssignment */:
+                // `a` in `({ ...a } = ...)`
+                return bindingElement.name;
+        }
+        var target = getTargetOfBindingOrAssignmentElement(bindingElement);
+        if (target && ts.isPropertyName(target)) {
+            return ts.isComputedPropertyName(target) && ts.isStringOrNumericLiteral(target.expression)
+                ? target.expression
+                : target;
+        }
+        ts.Debug.fail("Invalid property name for binding element.");
+    }
+    ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement;
+    /**
+     * Gets the elements of a BindingOrAssignmentPattern
+     */
+    function getElementsOfBindingOrAssignmentPattern(name) {
+        switch (name.kind) {
+            case 174 /* ObjectBindingPattern */:
+            case 175 /* ArrayBindingPattern */:
+            case 177 /* ArrayLiteralExpression */:
+                // `a` in `{a}`
+                // `a` in `[a]`
+                return name.elements;
+            case 178 /* ObjectLiteralExpression */:
+                // `a` in `{a}`
+                return name.properties;
+        }
+    }
+    ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern;
+    function convertToArrayAssignmentElement(element) {
+        if (ts.isBindingElement(element)) {
+            if (element.dotDotDotToken) {
+                ts.Debug.assertNode(element.name, ts.isIdentifier);
+                return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element);
+            }
+            var expression = convertToAssignmentElementTarget(element.name);
+            return element.initializer
+                ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element)
+                : expression;
+        }
+        ts.Debug.assertNode(element, ts.isExpression);
+        return element;
+    }
+    ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement;
+    function convertToObjectAssignmentElement(element) {
+        if (ts.isBindingElement(element)) {
+            if (element.dotDotDotToken) {
+                ts.Debug.assertNode(element.name, ts.isIdentifier);
+                return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element);
+            }
+            if (element.propertyName) {
+                var expression = convertToAssignmentElementTarget(element.name);
+                return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element);
+            }
+            ts.Debug.assertNode(element.name, ts.isIdentifier);
+            return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element);
+        }
+        ts.Debug.assertNode(element, ts.isObjectLiteralElementLike);
+        return element;
+    }
+    ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement;
+    function convertToAssignmentPattern(node) {
+        switch (node.kind) {
+            case 175 /* ArrayBindingPattern */:
+            case 177 /* ArrayLiteralExpression */:
+                return convertToArrayAssignmentPattern(node);
+            case 174 /* ObjectBindingPattern */:
+            case 178 /* ObjectLiteralExpression */:
+                return convertToObjectAssignmentPattern(node);
+        }
+    }
+    ts.convertToAssignmentPattern = convertToAssignmentPattern;
+    function convertToObjectAssignmentPattern(node) {
+        if (ts.isObjectBindingPattern(node)) {
+            return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node);
+        }
+        ts.Debug.assertNode(node, ts.isObjectLiteralExpression);
+        return node;
+    }
+    ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern;
+    function convertToArrayAssignmentPattern(node) {
+        if (ts.isArrayBindingPattern(node)) {
+            return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node);
+        }
+        ts.Debug.assertNode(node, ts.isArrayLiteralExpression);
+        return node;
+    }
+    ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern;
+    function convertToAssignmentElementTarget(node) {
+        if (ts.isBindingPattern(node)) {
+            return convertToAssignmentPattern(node);
+        }
+        ts.Debug.assertNode(node, ts.isExpression);
+        return node;
+    }
+    ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget;
+})(ts || (ts = {}));
+/// <reference path="checker.ts" />
+/// <reference path="factory.ts" />
+/// <reference path="utilities.ts" />
+var ts;
+(function (ts) {
+    function visitNode(node, visitor, test, lift) {
+        if (node === undefined || visitor === undefined) {
+            return node;
+        }
+        ts.aggregateTransformFlags(node);
+        var visited = visitor(node);
+        if (visited === node) {
+            return node;
+        }
+        var visitedNode;
+        if (visited === undefined) {
+            return undefined;
+        }
+        else if (ts.isArray(visited)) {
+            visitedNode = (lift || extractSingleNode)(visited);
+        }
+        else {
+            visitedNode = visited;
+        }
+        ts.Debug.assertNode(visitedNode, test);
+        ts.aggregateTransformFlags(visitedNode);
+        return visitedNode;
+    }
+    ts.visitNode = visitNode;
+    /**
+     * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
+     *
+     * @param nodes The NodeArray to visit.
+     * @param visitor The callback used to visit a Node.
+     * @param test A node test to execute for each node.
+     * @param start An optional value indicating the starting offset at which to start visiting.
+     * @param count An optional value indicating the maximum number of nodes to visit.
+     */
+    function visitNodes(nodes, visitor, test, start, count) {
+        if (nodes === undefined || visitor === undefined) {
+            return nodes;
+        }
+        var updated;
+        // Ensure start and count have valid values
+        var length = nodes.length;
+        if (start === undefined || start < 0) {
+            start = 0;
+        }
+        if (count === undefined || count > length - start) {
+            count = length - start;
+        }
+        if (start > 0 || count < length) {
+            // If we are not visiting all of the original nodes, we must always create a new array.
+            // Since this is a fragment of a node array, we do not copy over the previous location
+            // and will only copy over `hasTrailingComma` if we are including the last element.
+            updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
+        }
+        // Visit each original node.
+        for (var i = 0; i < count; i++) {
+            var node = nodes[i + start];
+            ts.aggregateTransformFlags(node);
+            var visited = node !== undefined ? visitor(node) : undefined;
+            if (updated !== undefined || visited === undefined || visited !== node) {
+                if (updated === undefined) {
+                    // Ensure we have a copy of `nodes`, up to the current index.
+                    updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
+                    ts.setTextRange(updated, nodes);
+                }
+                if (visited) {
+                    if (ts.isArray(visited)) {
+                        for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) {
+                            var visitedNode = visited_1[_i];
+                            ts.Debug.assertNode(visitedNode, test);
+                            ts.aggregateTransformFlags(visitedNode);
+                            updated.push(visitedNode);
+                        }
+                    }
+                    else {
+                        ts.Debug.assertNode(visited, test);
+                        ts.aggregateTransformFlags(visited);
+                        updated.push(visited);
+                    }
+                }
+            }
+        }
+        return updated || nodes;
+    }
+    ts.visitNodes = visitNodes;
+    /**
+     * Starts a new lexical environment and visits a statement list, ending the lexical environment
+     * and merging hoisted declarations upon completion.
+     */
+    function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) {
+        context.startLexicalEnvironment();
+        statements = visitNodes(statements, visitor, ts.isStatement, start);
+        if (ensureUseStrict && !ts.startsWithUseStrict(statements)) {
+            statements = ts.setTextRange(ts.createNodeArray([ts.createStatement(ts.createLiteral("use strict"))].concat(statements)), statements);
+        }
+        var declarations = context.endLexicalEnvironment();
+        return ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements);
+    }
+    ts.visitLexicalEnvironment = visitLexicalEnvironment;
+    /**
+     * Starts a new lexical environment and visits a parameter list, suspending the lexical
+     * environment upon completion.
+     */
+    function visitParameterList(nodes, visitor, context, nodesVisitor) {
+        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
+        context.startLexicalEnvironment();
+        var updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration);
+        context.suspendLexicalEnvironment();
+        return updated;
+    }
+    ts.visitParameterList = visitParameterList;
+    function visitFunctionBody(node, visitor, context) {
+        context.resumeLexicalEnvironment();
+        var updated = visitNode(node, visitor, ts.isConciseBody);
+        var declarations = context.endLexicalEnvironment();
+        if (ts.some(declarations)) {
+            var block = ts.convertToFunctionBody(updated);
+            var statements = ts.mergeLexicalEnvironment(block.statements, declarations);
+            return ts.updateBlock(block, statements);
+        }
+        return updated;
+    }
+    ts.visitFunctionBody = visitFunctionBody;
+    function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) {
+        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
+        if (node === undefined) {
+            return undefined;
+        }
+        var kind = node.kind;
+        // No need to visit nodes with no children.
+        if ((kind > 0 /* FirstToken */ && kind <= 142 /* LastToken */) || kind === 169 /* ThisType */) {
+            return node;
+        }
+        switch (kind) {
+            // Names
+            case 71 /* Identifier */:
+                return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
+            case 143 /* QualifiedName */:
+                return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier));
+            case 144 /* ComputedPropertyName */:
+                return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression));
+            // Signature elements
+            case 145 /* TypeParameter */:
+                return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode));
+            case 146 /* Parameter */:
+                return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
+            case 147 /* Decorator */:
+                return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression));
+            // Type elements
+            case 148 /* PropertySignature */:
+                return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
+            case 149 /* PropertyDeclaration */:
+                return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
+            case 150 /* MethodSignature */:
+                return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken));
+            case 151 /* MethodDeclaration */:
+                return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
+            case 152 /* Constructor */:
+                return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
+            case 153 /* GetAccessor */:
+                return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
+            case 154 /* SetAccessor */:
+                return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
+            case 155 /* CallSignature */:
+                return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            case 156 /* ConstructSignature */:
+                return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            case 157 /* IndexSignature */:
+                return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            // Types
+            case 158 /* TypePredicate */:
+                return ts.updateTypePredicateNode(node, visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode));
+            case 159 /* TypeReference */:
+                return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
+            case 160 /* FunctionType */:
+                return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            case 161 /* ConstructorType */:
+                return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            case 162 /* TypeQuery */:
+                return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName));
+            case 163 /* TypeLiteral */:
+                return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement));
+            case 164 /* ArrayType */:
+                return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode));
+            case 165 /* TupleType */:
+                return ts.updateTypleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode));
+            case 166 /* UnionType */:
+                return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
+            case 167 /* IntersectionType */:
+                return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
+            case 168 /* ParenthesizedType */:
+                return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode));
+            case 170 /* TypeOperator */:
+                return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode));
+            case 171 /* IndexedAccessType */:
+                return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode));
+            case 172 /* MappedType */:
+                return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode));
+            case 173 /* LiteralType */:
+                return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression));
+            // Binding patterns
+            case 174 /* ObjectBindingPattern */:
+                return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement));
+            case 175 /* ArrayBindingPattern */:
+                return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement));
+            case 176 /* BindingElement */:
+                return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression));
+            // Expression
+            case 177 /* ArrayLiteralExpression */:
+                return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression));
+            case 178 /* ObjectLiteralExpression */:
+                return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike));
+            case 179 /* PropertyAccessExpression */:
+                return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifier));
+            case 180 /* ElementAccessExpression */:
+                return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression));
+            case 181 /* CallExpression */:
+                return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
+            case 182 /* NewExpression */:
+                return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
+            case 183 /* TaggedTemplateExpression */:
+                return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral));
+            case 184 /* TypeAssertionExpression */:
+                return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
+            case 185 /* ParenthesizedExpression */:
+                return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 186 /* FunctionExpression */:
+                return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
+            case 187 /* ArrowFunction */:
+                return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context));
+            case 188 /* DeleteExpression */:
+                return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 189 /* TypeOfExpression */:
+                return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 190 /* VoidExpression */:
+                return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 191 /* AwaitExpression */:
+                return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 192 /* PrefixUnaryExpression */:
+                return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression));
+            case 193 /* PostfixUnaryExpression */:
+                return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression));
+            case 194 /* BinaryExpression */:
+                return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken));
+            case 195 /* ConditionalExpression */:
+                return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression));
+            case 196 /* TemplateExpression */:
+                return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan));
+            case 197 /* YieldExpression */:
+                return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression));
+            case 198 /* SpreadElement */:
+                return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 199 /* ClassExpression */:
+                return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
+            case 201 /* ExpressionWithTypeArguments */:
+                return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
+            case 202 /* AsExpression */:
+                return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode));
+            case 203 /* NonNullExpression */:
+                return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 204 /* MetaProperty */:
+                return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier));
+            // Misc
+            case 205 /* TemplateSpan */:
+                return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail));
+            // Element
+            case 207 /* Block */:
+                return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
+            case 208 /* VariableStatement */:
+                return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList));
+            case 210 /* ExpressionStatement */:
+                return ts.updateStatement(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 211 /* IfStatement */:
+                return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock));
+            case 212 /* DoStatement */:
+                return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression));
+            case 213 /* WhileStatement */:
+                return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 214 /* ForStatement */:
+                return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 215 /* ForInStatement */:
+                return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 216 /* ForOfStatement */:
+                return ts.updateForOf(node, node.awaitModifier, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 217 /* ContinueStatement */:
+                return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier));
+            case 218 /* BreakStatement */:
+                return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier));
+            case 219 /* ReturnStatement */:
+                return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 220 /* WithStatement */:
+                return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 221 /* SwitchStatement */:
+                return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock));
+            case 222 /* LabeledStatement */:
+                return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            case 223 /* ThrowStatement */:
+                return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 224 /* TryStatement */:
+                return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock));
+            case 226 /* VariableDeclaration */:
+                return ts.updateVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
+            case 227 /* VariableDeclarationList */:
+                return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration));
+            case 228 /* FunctionDeclaration */:
+                return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
+            case 229 /* ClassDeclaration */:
+                return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
+            case 230 /* InterfaceDeclaration */:
+                return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement));
+            case 231 /* TypeAliasDeclaration */:
+                return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
+            case 232 /* EnumDeclaration */:
+                return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember));
+            case 233 /* ModuleDeclaration */:
+                return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody));
+            case 234 /* ModuleBlock */:
+                return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
+            case 235 /* CaseBlock */:
+                return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause));
+            case 236 /* NamespaceExportDeclaration */:
+                return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier));
+            case 237 /* ImportEqualsDeclaration */:
+                return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference));
+            case 238 /* ImportDeclaration */:
+                return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
+            case 239 /* ImportClause */:
+                return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings));
+            case 240 /* NamespaceImport */:
+                return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier));
+            case 241 /* NamedImports */:
+                return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier));
+            case 242 /* ImportSpecifier */:
+                return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
+            case 243 /* ExportAssignment */:
+                return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression));
+            case 244 /* ExportDeclaration */:
+                return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExports), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
+            case 245 /* NamedExports */:
+                return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier));
+            case 246 /* ExportSpecifier */:
+                return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
+            // Module references
+            case 248 /* ExternalModuleReference */:
+                return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression));
+            // JSX
+            case 249 /* JsxElement */:
+                return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement));
+            case 250 /* JsxSelfClosingElement */:
+                return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes));
+            case 251 /* JsxOpeningElement */:
+                return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes));
+            case 252 /* JsxClosingElement */:
+                return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression));
+            case 253 /* JsxAttribute */:
+                return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression));
+            case 254 /* JsxAttributes */:
+                return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike));
+            case 255 /* JsxSpreadAttribute */:
+                return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 256 /* JsxExpression */:
+                return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression));
+            // Clauses
+            case 257 /* CaseClause */:
+                return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement));
+            case 258 /* DefaultClause */:
+                return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement));
+            case 259 /* HeritageClause */:
+                return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments));
+            case 260 /* CatchClause */:
+                return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock));
+            // Property assignments
+            case 261 /* PropertyAssignment */:
+                return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
+            case 262 /* ShorthandPropertyAssignment */:
+                return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression));
+            case 263 /* SpreadAssignment */:
+                return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression));
+            // Enum
+            case 264 /* EnumMember */:
+                return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
+            // Top-level nodes
+            case 265 /* SourceFile */:
+                return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context));
+            // Transformation nodes
+            case 288 /* PartiallyEmittedExpression */:
+                return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression));
+            case 289 /* CommaListExpression */:
+                return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression));
+            default:
+                // No need to visit nodes with no children.
+                return node;
+        }
+    }
+    ts.visitEachChild = visitEachChild;
+    /**
+     * Extracts the single node from a NodeArray.
+     *
+     * @param nodes The NodeArray.
+     */
+    function extractSingleNode(nodes) {
+        ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
+        return ts.singleOrUndefined(nodes);
+    }
+})(ts || (ts = {}));
+/* @internal */
+(function (ts) {
+    function reduceNode(node, f, initial) {
+        return node ? f(initial, node) : initial;
+    }
+    function reduceNodeArray(nodes, f, initial) {
+        return nodes ? f(initial, nodes) : initial;
+    }
+    /**
+     * Similar to `reduceLeft`, performs a reduction against each child of a node.
+     * NOTE: Unlike `forEachChild`, this does *not* visit every node.
+     *
+     * @param node The node containing the children to reduce.
+     * @param initial The initial value to supply to the reduction.
+     * @param f The callback function
+     */
+    function reduceEachChild(node, initial, cbNode, cbNodeArray) {
+        if (node === undefined) {
+            return initial;
+        }
+        var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft;
+        var cbNodes = cbNodeArray || cbNode;
+        var kind = node.kind;
+        // No need to visit nodes with no children.
+        if ((kind > 0 /* FirstToken */ && kind <= 142 /* LastToken */)) {
+            return initial;
+        }
+        // We do not yet support types.
+        if ((kind >= 158 /* TypePredicate */ && kind <= 173 /* LiteralType */)) {
+            return initial;
+        }
+        var result = initial;
+        switch (node.kind) {
+            // Leaf nodes
+            case 206 /* SemicolonClassElement */:
+            case 209 /* EmptyStatement */:
+            case 200 /* OmittedExpression */:
+            case 225 /* DebuggerStatement */:
+            case 287 /* NotEmittedStatement */:
+                // No need to visit nodes with no children.
+                break;
+            // Names
+            case 143 /* QualifiedName */:
+                result = reduceNode(node.left, cbNode, result);
+                result = reduceNode(node.right, cbNode, result);
+                break;
+            case 144 /* ComputedPropertyName */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            // Signature elements
+            case 146 /* Parameter */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 147 /* Decorator */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            // Type member
+            case 148 /* PropertySignature */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.questionToken, cbNode, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 149 /* PropertyDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 151 /* MethodDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 152 /* Constructor */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 153 /* GetAccessor */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 154 /* SetAccessor */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            // Binding patterns
+            case 174 /* ObjectBindingPattern */:
+            case 175 /* ArrayBindingPattern */:
+                result = reduceNodes(node.elements, cbNodes, result);
+                break;
+            case 176 /* BindingElement */:
+                result = reduceNode(node.propertyName, cbNode, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            // Expression
+            case 177 /* ArrayLiteralExpression */:
+                result = reduceNodes(node.elements, cbNodes, result);
+                break;
+            case 178 /* ObjectLiteralExpression */:
+                result = reduceNodes(node.properties, cbNodes, result);
+                break;
+            case 179 /* PropertyAccessExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.name, cbNode, result);
+                break;
+            case 180 /* ElementAccessExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.argumentExpression, cbNode, result);
+                break;
+            case 181 /* CallExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNodes(node.typeArguments, cbNodes, result);
+                result = reduceNodes(node.arguments, cbNodes, result);
+                break;
+            case 182 /* NewExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNodes(node.typeArguments, cbNodes, result);
+                result = reduceNodes(node.arguments, cbNodes, result);
+                break;
+            case 183 /* TaggedTemplateExpression */:
+                result = reduceNode(node.tag, cbNode, result);
+                result = reduceNode(node.template, cbNode, result);
+                break;
+            case 184 /* TypeAssertionExpression */:
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 186 /* FunctionExpression */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 187 /* ArrowFunction */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 185 /* ParenthesizedExpression */:
+            case 188 /* DeleteExpression */:
+            case 189 /* TypeOfExpression */:
+            case 190 /* VoidExpression */:
+            case 191 /* AwaitExpression */:
+            case 197 /* YieldExpression */:
+            case 198 /* SpreadElement */:
+            case 203 /* NonNullExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 192 /* PrefixUnaryExpression */:
+            case 193 /* PostfixUnaryExpression */:
+                result = reduceNode(node.operand, cbNode, result);
+                break;
+            case 194 /* BinaryExpression */:
+                result = reduceNode(node.left, cbNode, result);
+                result = reduceNode(node.right, cbNode, result);
+                break;
+            case 195 /* ConditionalExpression */:
+                result = reduceNode(node.condition, cbNode, result);
+                result = reduceNode(node.whenTrue, cbNode, result);
+                result = reduceNode(node.whenFalse, cbNode, result);
+                break;
+            case 196 /* TemplateExpression */:
+                result = reduceNode(node.head, cbNode, result);
+                result = reduceNodes(node.templateSpans, cbNodes, result);
+                break;
+            case 199 /* ClassExpression */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.heritageClauses, cbNodes, result);
+                result = reduceNodes(node.members, cbNodes, result);
+                break;
+            case 201 /* ExpressionWithTypeArguments */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNodes(node.typeArguments, cbNodes, result);
+                break;
+            case 202 /* AsExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.type, cbNode, result);
+                break;
+            // Misc
+            case 205 /* TemplateSpan */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.literal, cbNode, result);
+                break;
+            // Element
+            case 207 /* Block */:
+                result = reduceNodes(node.statements, cbNodes, result);
+                break;
+            case 208 /* VariableStatement */:
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.declarationList, cbNode, result);
+                break;
+            case 210 /* ExpressionStatement */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 211 /* IfStatement */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.thenStatement, cbNode, result);
+                result = reduceNode(node.elseStatement, cbNode, result);
+                break;
+            case 212 /* DoStatement */:
+                result = reduceNode(node.statement, cbNode, result);
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 213 /* WhileStatement */:
+            case 220 /* WithStatement */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.statement, cbNode, result);
+                break;
+            case 214 /* ForStatement */:
+                result = reduceNode(node.initializer, cbNode, result);
+                result = reduceNode(node.condition, cbNode, result);
+                result = reduceNode(node.incrementor, cbNode, result);
+                result = reduceNode(node.statement, cbNode, result);
+                break;
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+                result = reduceNode(node.initializer, cbNode, result);
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.statement, cbNode, result);
+                break;
+            case 219 /* ReturnStatement */:
+            case 223 /* ThrowStatement */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 221 /* SwitchStatement */:
+                result = reduceNode(node.expression, cbNode, result);
+                result = reduceNode(node.caseBlock, cbNode, result);
+                break;
+            case 222 /* LabeledStatement */:
+                result = reduceNode(node.label, cbNode, result);
+                result = reduceNode(node.statement, cbNode, result);
+                break;
+            case 224 /* TryStatement */:
+                result = reduceNode(node.tryBlock, cbNode, result);
+                result = reduceNode(node.catchClause, cbNode, result);
+                result = reduceNode(node.finallyBlock, cbNode, result);
+                break;
+            case 226 /* VariableDeclaration */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 227 /* VariableDeclarationList */:
+                result = reduceNodes(node.declarations, cbNodes, result);
+                break;
+            case 228 /* FunctionDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.parameters, cbNodes, result);
+                result = reduceNode(node.type, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 229 /* ClassDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.typeParameters, cbNodes, result);
+                result = reduceNodes(node.heritageClauses, cbNodes, result);
+                result = reduceNodes(node.members, cbNodes, result);
+                break;
+            case 232 /* EnumDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNodes(node.members, cbNodes, result);
+                break;
+            case 233 /* ModuleDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.body, cbNode, result);
+                break;
+            case 234 /* ModuleBlock */:
+                result = reduceNodes(node.statements, cbNodes, result);
+                break;
+            case 235 /* CaseBlock */:
+                result = reduceNodes(node.clauses, cbNodes, result);
+                break;
+            case 237 /* ImportEqualsDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.moduleReference, cbNode, result);
+                break;
+            case 238 /* ImportDeclaration */:
+                result = reduceNodes(node.decorators, cbNodes, result);
+                result = reduceNodes(node.modifiers, cbNodes, result);
+                result = reduceNode(node.importClause, cbNode, result);
+                result = reduceNode(node.moduleSpecifier, cbNode, result);
+                break;
+            case 239 /* ImportClause */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.namedBindings, cbNode, result);
+                break;
+            case 240 /* NamespaceImport */:
+                result = reduceNode(node.name, cbNode, result);
+                break;
+            case 241 /* NamedImports */:
+            case 245 /* NamedExports */:
+                result = reduceNodes(node.elements, cbNodes, result);
+                break;
+            case 242 /* ImportSpecifier */:
+            case 246 /* ExportSpecifier */:
+                result = reduceNode(node.propertyName, cbNode, result);
+                result = reduceNode(node.name, cbNode, result);
+                break;
+            case 243 /* ExportAssignment */:
+                result = ts.reduceLeft(node.decorators, cbNode, result);
+                result = ts.reduceLeft(node.modifiers, cbNode, result);
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 244 /* ExportDeclaration */:
+                result = ts.reduceLeft(node.decorators, cbNode, result);
+                result = ts.reduceLeft(node.modifiers, cbNode, result);
+                result = reduceNode(node.exportClause, cbNode, result);
+                result = reduceNode(node.moduleSpecifier, cbNode, result);
+                break;
+            // Module references
+            case 248 /* ExternalModuleReference */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            // JSX
+            case 249 /* JsxElement */:
+                result = reduceNode(node.openingElement, cbNode, result);
+                result = ts.reduceLeft(node.children, cbNode, result);
+                result = reduceNode(node.closingElement, cbNode, result);
+                break;
+            case 250 /* JsxSelfClosingElement */:
+            case 251 /* JsxOpeningElement */:
+                result = reduceNode(node.tagName, cbNode, result);
+                result = reduceNode(node.attributes, cbNode, result);
+                break;
+            case 254 /* JsxAttributes */:
+                result = reduceNodes(node.properties, cbNodes, result);
+                break;
+            case 252 /* JsxClosingElement */:
+                result = reduceNode(node.tagName, cbNode, result);
+                break;
+            case 253 /* JsxAttribute */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 255 /* JsxSpreadAttribute */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 256 /* JsxExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            // Clauses
+            case 257 /* CaseClause */:
+                result = reduceNode(node.expression, cbNode, result);
+            // falls through
+            case 258 /* DefaultClause */:
+                result = reduceNodes(node.statements, cbNodes, result);
+                break;
+            case 259 /* HeritageClause */:
+                result = reduceNodes(node.types, cbNodes, result);
+                break;
+            case 260 /* CatchClause */:
+                result = reduceNode(node.variableDeclaration, cbNode, result);
+                result = reduceNode(node.block, cbNode, result);
+                break;
+            // Property assignments
+            case 261 /* PropertyAssignment */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            case 262 /* ShorthandPropertyAssignment */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.objectAssignmentInitializer, cbNode, result);
+                break;
+            case 263 /* SpreadAssignment */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            // Enum
+            case 264 /* EnumMember */:
+                result = reduceNode(node.name, cbNode, result);
+                result = reduceNode(node.initializer, cbNode, result);
+                break;
+            // Top-level nodes
+            case 265 /* SourceFile */:
+                result = reduceNodes(node.statements, cbNodes, result);
+                break;
+            // Transformation nodes
+            case 288 /* PartiallyEmittedExpression */:
+                result = reduceNode(node.expression, cbNode, result);
+                break;
+            case 289 /* CommaListExpression */:
+                result = reduceNodes(node.elements, cbNodes, result);
+                break;
+            default:
+                break;
+        }
+        return result;
+    }
+    ts.reduceEachChild = reduceEachChild;
+    function mergeLexicalEnvironment(statements, declarations) {
+        if (!ts.some(declarations)) {
+            return statements;
+        }
+        return ts.isNodeArray(statements)
+            ? ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements)
+            : ts.addRange(statements, declarations);
+    }
+    ts.mergeLexicalEnvironment = mergeLexicalEnvironment;
+    /**
+     * Lifts a NodeArray containing only Statement nodes to a block.
+     *
+     * @param nodes The NodeArray.
+     */
+    function liftToBlock(nodes) {
+        Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block.");
+        return ts.singleOrUndefined(nodes) || ts.createBlock(nodes);
+    }
+    ts.liftToBlock = liftToBlock;
+    /**
+     * Aggregates the TransformFlags for a Node and its subtree.
+     */
+    function aggregateTransformFlags(node) {
+        aggregateTransformFlagsForNode(node);
+        return node;
+    }
+    ts.aggregateTransformFlags = aggregateTransformFlags;
+    /**
+     * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
+     * computed first, then the transform flags for the current node are computed from the subtree
+     * flags and the state of the current node. Finally, the transform flags of the node are
+     * returned, excluding any flags that should not be included in its parent node's subtree
+     * flags.
+     */
+    function aggregateTransformFlagsForNode(node) {
+        if (node === undefined) {
+            return 0 /* None */;
+        }
+        if (node.transformFlags & 536870912 /* HasComputedFlags */) {
+            return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind);
+        }
+        var subtreeFlags = aggregateTransformFlagsForSubtree(node);
+        return ts.computeTransformFlagsForNode(node, subtreeFlags);
+    }
+    function aggregateTransformFlagsForNodeArray(nodes) {
+        if (nodes === undefined) {
+            return 0 /* None */;
+        }
+        var subtreeFlags = 0 /* None */;
+        var nodeArrayFlags = 0 /* None */;
+        for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
+            var node = nodes_3[_i];
+            subtreeFlags |= aggregateTransformFlagsForNode(node);
+            nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
+        }
+        nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
+        return subtreeFlags;
+    }
+    /**
+     * Aggregates the transform flags for the subtree of a node.
+     */
+    function aggregateTransformFlagsForSubtree(node) {
+        // We do not transform ambient declarations or types, so there is no need to
+        // recursively aggregate transform flags.
+        if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 201 /* ExpressionWithTypeArguments */)) {
+            return 0 /* None */;
+        }
+        // Aggregate the transform flags of each child.
+        return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
+    }
+    /**
+     * Aggregates the TransformFlags of a child node with the TransformFlags of its
+     * siblings.
+     */
+    function aggregateTransformFlagsForChildNode(transformFlags, node) {
+        return transformFlags | aggregateTransformFlagsForNode(node);
+    }
+    function aggregateTransformFlagsForChildNodes(transformFlags, nodes) {
+        return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
+    }
+    var Debug;
+    (function (Debug) {
+        var isDebugInfoEnabled = false;
+        Debug.failBadSyntaxKind = Debug.shouldAssert(1 /* Normal */)
+            ? function (node, message) { return Debug.fail((message || "Unexpected node.") + "\r\nNode " + ts.formatSyntaxKind(node.kind) + " was unexpected.", Debug.failBadSyntaxKind); }
+            : ts.noop;
+        Debug.assertEachNode = Debug.shouldAssert(1 /* Normal */)
+            ? function (nodes, test, message) { return Debug.assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertEachNode); }
+            : ts.noop;
+        Debug.assertNode = Debug.shouldAssert(1 /* Normal */)
+            ? function (node, test, message) { return Debug.assert(test === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertNode); }
+            : ts.noop;
+        Debug.assertOptionalNode = Debug.shouldAssert(1 /* Normal */)
+            ? function (node, test, message) { return Debug.assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertOptionalNode); }
+            : ts.noop;
+        Debug.assertOptionalToken = Debug.shouldAssert(1 /* Normal */)
+            ? function (node, kind, message) { return Debug.assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was not a '" + ts.formatSyntaxKind(kind) + "' token."; }, Debug.assertOptionalToken); }
+            : ts.noop;
+        Debug.assertMissingNode = Debug.shouldAssert(1 /* Normal */)
+            ? function (node, message) { return Debug.assert(node === undefined, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was unexpected'."; }, Debug.assertMissingNode); }
+            : ts.noop;
+        /**
+         * Injects debug information into frequently used types.
+         */
+        function enableDebugInfo() {
+            if (isDebugInfoEnabled)
+                return;
+            // Add additional properties in debug mode to assist with debugging.
+            Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, {
+                "__debugFlags": { get: function () { return ts.formatSymbolFlags(this.flags); } }
+            });
+            Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, {
+                "__debugFlags": { get: function () { return ts.formatTypeFlags(this.flags); } },
+                "__debugObjectFlags": { get: function () { return this.flags & 32768 /* Object */ ? ts.formatObjectFlags(this.objectFlags) : ""; } },
+                "__debugTypeToString": { value: function () { return this.checker.typeToString(this); } },
+            });
+            var nodeConstructors = [
+                ts.objectAllocator.getNodeConstructor(),
+                ts.objectAllocator.getIdentifierConstructor(),
+                ts.objectAllocator.getTokenConstructor(),
+                ts.objectAllocator.getSourceFileConstructor()
+            ];
+            for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) {
+                var ctor = nodeConstructors_1[_i];
+                if (!ctor.prototype.hasOwnProperty("__debugKind")) {
+                    Object.defineProperties(ctor.prototype, {
+                        "__debugKind": { get: function () { return ts.formatSyntaxKind(this.kind); } },
+                        "__debugModifierFlags": { get: function () { return ts.formatModifierFlags(ts.getModifierFlagsNoCache(this)); } },
+                        "__debugTransformFlags": { get: function () { return ts.formatTransformFlags(this.transformFlags); } },
+                        "__debugEmitFlags": { get: function () { return ts.formatEmitFlags(ts.getEmitFlags(this)); } },
+                        "__debugGetText": {
+                            value: function (includeTrivia) {
+                                if (ts.nodeIsSynthesized(this))
+                                    return "";
+                                var parseNode = ts.getParseTreeNode(this);
+                                var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode);
+                                return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
+                            }
+                        }
+                    });
+                }
+            }
+            isDebugInfoEnabled = true;
+        }
+        Debug.enableDebugInfo = enableDebugInfo;
+    })(Debug = ts.Debug || (ts.Debug = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    function getOriginalNodeId(node) {
+        node = ts.getOriginalNode(node);
+        return node ? ts.getNodeId(node) : 0;
+    }
+    ts.getOriginalNodeId = getOriginalNodeId;
+    function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) {
+        var externalImports = [];
+        var exportSpecifiers = ts.createMultiMap();
+        var exportedBindings = [];
+        var uniqueExports = ts.createMap();
+        var exportedNames;
+        var hasExportDefault = false;
+        var exportEquals = undefined;
+        var hasExportStarsToExportValues = false;
+        for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
+            var node = _a[_i];
+            switch (node.kind) {
+                case 238 /* ImportDeclaration */:
+                    // import "mod"
+                    // import x from "mod"
+                    // import * as x from "mod"
+                    // import { x, y } from "mod"
+                    externalImports.push(node);
+                    break;
+                case 237 /* ImportEqualsDeclaration */:
+                    if (node.moduleReference.kind === 248 /* ExternalModuleReference */) {
+                        // import x = require("mod")
+                        externalImports.push(node);
+                    }
+                    break;
+                case 244 /* ExportDeclaration */:
+                    if (node.moduleSpecifier) {
+                        if (!node.exportClause) {
+                            // export * from "mod"
+                            externalImports.push(node);
+                            hasExportStarsToExportValues = true;
+                        }
+                        else {
+                            // export { x, y } from "mod"
+                            externalImports.push(node);
+                        }
+                    }
+                    else {
+                        // export { x, y }
+                        for (var _b = 0, _c = node.exportClause.elements; _b < _c.length; _b++) {
+                            var specifier = _c[_b];
+                            if (!uniqueExports.get(ts.idText(specifier.name))) {
+                                var name = specifier.propertyName || specifier.name;
+                                exportSpecifiers.add(ts.idText(name), specifier);
+                                var decl = resolver.getReferencedImportDeclaration(name)
+                                    || resolver.getReferencedValueDeclaration(name);
+                                if (decl) {
+                                    multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
+                                }
+                                uniqueExports.set(ts.idText(specifier.name), true);
+                                exportedNames = ts.append(exportedNames, specifier.name);
+                            }
+                        }
+                    }
+                    break;
+                case 243 /* ExportAssignment */:
+                    if (node.isExportEquals && !exportEquals) {
+                        // export = x
+                        exportEquals = node;
+                    }
+                    break;
+                case 208 /* VariableStatement */:
+                    if (ts.hasModifier(node, 1 /* Export */)) {
+                        for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) {
+                            var decl = _e[_d];
+                            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
+                        }
+                    }
+                    break;
+                case 228 /* FunctionDeclaration */:
+                    if (ts.hasModifier(node, 1 /* Export */)) {
+                        if (ts.hasModifier(node, 512 /* Default */)) {
+                            // export default function() { }
+                            if (!hasExportDefault) {
+                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
+                                hasExportDefault = true;
+                            }
+                        }
+                        else {
+                            // export function x() { }
+                            var name = node.name;
+                            if (!uniqueExports.get(ts.idText(name))) {
+                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
+                                uniqueExports.set(ts.idText(name), true);
+                                exportedNames = ts.append(exportedNames, name);
+                            }
+                        }
+                    }
+                    break;
+                case 229 /* ClassDeclaration */:
+                    if (ts.hasModifier(node, 1 /* Export */)) {
+                        if (ts.hasModifier(node, 512 /* Default */)) {
+                            // export default class { }
+                            if (!hasExportDefault) {
+                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
+                                hasExportDefault = true;
+                            }
+                        }
+                        else {
+                            // export class x { }
+                            var name = node.name;
+                            if (name && !uniqueExports.get(ts.idText(name))) {
+                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
+                                uniqueExports.set(ts.idText(name), true);
+                                exportedNames = ts.append(exportedNames, name);
+                            }
+                        }
+                    }
+                    break;
+            }
+        }
+        var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
+        var externalHelpersImportDeclaration = externalHelpersModuleName && ts.createImportDeclaration(
+        /*decorators*/ undefined, 
+        /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText));
+        if (externalHelpersImportDeclaration) {
+            externalImports.unshift(externalHelpersImportDeclaration);
+        }
+        return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration };
+    }
+    ts.collectExternalModuleInfo = collectExternalModuleInfo;
+    function collectExportedVariableInfo(decl, uniqueExports, exportedNames) {
+        if (ts.isBindingPattern(decl.name)) {
+            for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
+                var element = _a[_i];
+                if (!ts.isOmittedExpression(element)) {
+                    exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
+                }
+            }
+        }
+        else if (!ts.isGeneratedIdentifier(decl.name)) {
+            var text = ts.idText(decl.name);
+            if (!uniqueExports.get(text)) {
+                uniqueExports.set(text, true);
+                exportedNames = ts.append(exportedNames, decl.name);
+            }
+        }
+        return exportedNames;
+    }
+    /** Use a sparse array as a multi-map. */
+    function multiMapSparseArrayAdd(map, key, value) {
+        var values = map[key];
+        if (values) {
+            values.push(value);
+        }
+        else {
+            map[key] = values = [value];
+        }
+        return values;
+    }
+    /**
+     * Used in the module transformer to check if an expression is reasonably without sideeffect,
+     *  and thus better to copy into multiple places rather than to cache in a temporary variable
+     *  - this is mostly subjective beyond the requirement that the expression not be sideeffecting
+     */
+    function isSimpleCopiableExpression(expression) {
+        return expression.kind === 9 /* StringLiteral */ ||
+            expression.kind === 8 /* NumericLiteral */ ||
+            expression.kind === 13 /* NoSubstitutionTemplateLiteral */ ||
+            ts.isKeyword(expression.kind) ||
+            ts.isIdentifier(expression);
+    }
+    ts.isSimpleCopiableExpression = isSimpleCopiableExpression;
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    var FlattenLevel;
+    (function (FlattenLevel) {
+        FlattenLevel[FlattenLevel["All"] = 0] = "All";
+        FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest";
+    })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {}));
+    /**
+     * Flattens a DestructuringAssignment or a VariableDeclaration to an expression.
+     *
+     * @param node The node to flatten.
+     * @param visitor An optional visitor used to visit initializers.
+     * @param context The transformation context.
+     * @param level Indicates the extent to which flattening should occur.
+     * @param needsValue An optional value indicating whether the value from the right-hand-side of
+     * the destructuring assignment is needed as part of a larger expression.
+     * @param createAssignmentCallback An optional callback used to create the assignment expression.
+     */
+    function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
+        var location = node;
+        var value;
+        if (ts.isDestructuringAssignment(node)) {
+            value = node.right;
+            while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) {
+                if (ts.isDestructuringAssignment(value)) {
+                    location = node = value;
+                    value = node.right;
+                }
+                else {
+                    return value;
+                }
+            }
+        }
+        var expressions;
+        var flattenContext = {
+            context: context,
+            level: level,
+            downlevelIteration: context.getCompilerOptions().downlevelIteration,
+            hoistTempVariables: true,
+            emitExpression: emitExpression,
+            emitBindingOrAssignment: emitBindingOrAssignment,
+            createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
+            createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern,
+            createArrayBindingOrAssignmentElement: makeAssignmentElement,
+            visitor: visitor
+        };
+        if (value) {
+            value = ts.visitNode(value, visitor, ts.isExpression);
+            if (needsValue) {
+                // If the right-hand value of the destructuring assignment needs to be preserved (as
+                // is the case when the destructuring assignment is part of a larger expression),
+                // then we need to cache the right-hand value.
+                //
+                // The source map location for the assignment should point to the entire binary
+                // expression.
+                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
+            }
+            else if (ts.nodeIsSynthesized(node)) {
+                // Generally, the source map location for a destructuring assignment is the root
+                // expression.
+                //
+                // However, if the root expression is synthesized (as in the case
+                // of the initializer when transforming a ForOfStatement), then the source map
+                // location should point to the right-hand value of the expression.
+                location = value;
+            }
+        }
+        flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node));
+        if (value && needsValue) {
+            if (!ts.some(expressions)) {
+                return value;
+            }
+            expressions.push(value);
+        }
+        return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression();
+        function emitExpression(expression) {
+            // NOTE: this completely disables source maps, but aligns with the behavior of
+            //       `emitAssignment` in the old emitter.
+            ts.setEmitFlags(expression, 64 /* NoNestedSourceMaps */);
+            ts.aggregateTransformFlags(expression);
+            expressions = ts.append(expressions, expression);
+        }
+        function emitBindingOrAssignment(target, value, location, original) {
+            ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression);
+            var expression = createAssignmentCallback
+                ? createAssignmentCallback(target, value, location)
+                : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location);
+            expression.original = original;
+            emitExpression(expression);
+        }
+    }
+    ts.flattenDestructuringAssignment = flattenDestructuringAssignment;
+    /**
+     * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
+     *
+     * @param node The node to flatten.
+     * @param visitor An optional visitor used to visit initializers.
+     * @param context The transformation context.
+     * @param boundValue The value bound to the declaration.
+     * @param skipInitializer A value indicating whether to ignore the initializer of `node`.
+     * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
+     * @param level Indicates the extent to which flattening should occur.
+     */
+    function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) {
+        var pendingExpressions;
+        var pendingDeclarations = [];
+        var declarations = [];
+        var flattenContext = {
+            context: context,
+            level: level,
+            downlevelIteration: context.getCompilerOptions().downlevelIteration,
+            hoistTempVariables: hoistTempVariables,
+            emitExpression: emitExpression,
+            emitBindingOrAssignment: emitBindingOrAssignment,
+            createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
+            createObjectBindingOrAssignmentPattern: makeObjectBindingPattern,
+            createArrayBindingOrAssignmentElement: makeBindingElement,
+            visitor: visitor
+        };
+        flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
+        if (pendingExpressions) {
+            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
+            if (hoistTempVariables) {
+                var value = ts.inlineExpressions(pendingExpressions);
+                pendingExpressions = undefined;
+                emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
+            }
+            else {
+                context.hoistVariableDeclaration(temp);
+                var pendingDeclaration = ts.lastOrUndefined(pendingDeclarations);
+                pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value));
+                ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
+                pendingDeclaration.value = temp;
+            }
+        }
+        for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) {
+            var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original;
+            var variable = ts.createVariableDeclaration(name, 
+            /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value);
+            variable.original = original;
+            ts.setTextRange(variable, location);
+            if (ts.isIdentifier(name)) {
+                ts.setEmitFlags(variable, 64 /* NoNestedSourceMaps */);
+            }
+            ts.aggregateTransformFlags(variable);
+            declarations.push(variable);
+        }
+        return declarations;
+        function emitExpression(value) {
+            pendingExpressions = ts.append(pendingExpressions, value);
+        }
+        function emitBindingOrAssignment(target, value, location, original) {
+            ts.Debug.assertNode(target, ts.isBindingName);
+            if (pendingExpressions) {
+                value = ts.inlineExpressions(ts.append(pendingExpressions, value));
+                pendingExpressions = undefined;
+            }
+            pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original });
+        }
+    }
+    ts.flattenDestructuringBinding = flattenDestructuringBinding;
+    /**
+     * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments.
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param element The element to flatten.
+     * @param value The current RHS value to assign to the element.
+     * @param location The location to use for source maps and comments.
+     * @param skipInitializer An optional value indicating whether to include the initializer
+     * for the element.
+     */
+    function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
+        if (!skipInitializer) {
+            var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression);
+            if (initializer) {
+                // Combine value and initializer
+                value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer;
+            }
+            else if (!value) {
+                // Use 'void 0' in absence of value and initializer
+                value = ts.createVoidZero();
+            }
+        }
+        var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element);
+        if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) {
+            flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
+        }
+        else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) {
+            flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
+        }
+        else {
+            flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element);
+        }
+    }
+    /**
+     * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments.
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param parent The parent element of the pattern.
+     * @param pattern The ObjectBindingOrAssignmentPattern to flatten.
+     * @param value The current RHS value to assign to the element.
+     * @param location The location to use for source maps and comments.
+     */
+    function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
+        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
+        var numElements = elements.length;
+        if (numElements !== 1) {
+            // For anything other than a single-element destructuring we need to generate a temporary
+            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
+            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
+            // so in that case, we'll intentionally create that temporary.
+            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
+            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
+        }
+        var bindingElements;
+        var computedTempVariables;
+        for (var i = 0; i < numElements; i++) {
+            var element = elements[i];
+            if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
+                var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element);
+                if (flattenContext.level >= 1 /* ObjectRest */
+                    && !(element.transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */))
+                    && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */))
+                    && !ts.isComputedPropertyName(propertyName)) {
+                    bindingElements = ts.append(bindingElements, element);
+                }
+                else {
+                    if (bindingElements) {
+                        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
+                        bindingElements = undefined;
+                    }
+                    var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
+                    if (ts.isComputedPropertyName(propertyName)) {
+                        computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression);
+                    }
+                    flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
+                }
+            }
+            else if (i === numElements - 1) {
+                if (bindingElements) {
+                    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
+                    bindingElements = undefined;
+                }
+                var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern);
+                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
+            }
+        }
+        if (bindingElements) {
+            flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
+        }
+    }
+    /**
+     * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments.
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param parent The parent element of the pattern.
+     * @param pattern The ArrayBindingOrAssignmentPattern to flatten.
+     * @param value The current RHS value to assign to the element.
+     * @param location The location to use for source maps and comments.
+     */
+    function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
+        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
+        var numElements = elements.length;
+        if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
+            // Read the elements of the iterable into an array
+            value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
+                ? undefined
+                : numElements, location), 
+            /*reuseIdentifierExpressions*/ false, location);
+        }
+        else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)
+            || ts.every(elements, ts.isOmittedExpression)) {
+            // For anything other than a single-element destructuring we need to generate a temporary
+            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
+            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
+            // so in that case, we'll intentionally create that temporary.
+            // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]",
+            // then we will create temporary variable.
+            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
+            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
+        }
+        var bindingElements;
+        var restContainingElements;
+        for (var i = 0; i < numElements; i++) {
+            var element = elements[i];
+            if (flattenContext.level >= 1 /* ObjectRest */) {
+                // If an array pattern contains an ObjectRest, we must cache the result so that we
+                // can perform the ObjectRest destructuring in a different declaration
+                if (element.transformFlags & 1048576 /* ContainsObjectRest */) {
+                    var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
+                    if (flattenContext.hoistTempVariables) {
+                        flattenContext.context.hoistVariableDeclaration(temp);
+                    }
+                    restContainingElements = ts.append(restContainingElements, [temp, element]);
+                    bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
+                }
+                else {
+                    bindingElements = ts.append(bindingElements, element);
+                }
+            }
+            else if (ts.isOmittedExpression(element)) {
+                continue;
+            }
+            else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
+                var rhsValue = ts.createElementAccess(value, i);
+                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
+            }
+            else if (i === numElements - 1) {
+                var rhsValue = ts.createArraySlice(value, i);
+                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
+            }
+        }
+        if (bindingElements) {
+            flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
+        }
+        if (restContainingElements) {
+            for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) {
+                var _a = restContainingElements_1[_i], id = _a[0], element = _a[1];
+                flattenBindingOrAssignmentElement(flattenContext, element, id, element);
+            }
+        }
+    }
+    /**
+     * Creates an expression used to provide a default value if a value is `undefined` at runtime.
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param value The RHS value to test.
+     * @param defaultValue The default value to use if `value` is `undefined` at runtime.
+     * @param location The location to use for source maps and comments.
+     */
+    function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
+        value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
+        return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value);
+    }
+    /**
+     * Creates either a PropertyAccessExpression or an ElementAccessExpression for the
+     * right-hand side of a transformed destructuring assignment.
+     *
+     * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param value The RHS value that is the source of the property.
+     * @param propertyName The destructuring property name.
+     */
+    function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
+        if (ts.isComputedPropertyName(propertyName)) {
+            var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
+            return ts.createElementAccess(value, argumentExpression);
+        }
+        else if (ts.isStringOrNumericLiteral(propertyName)) {
+            var argumentExpression = ts.getSynthesizedClone(propertyName);
+            argumentExpression.text = argumentExpression.text;
+            return ts.createElementAccess(value, argumentExpression);
+        }
+        else {
+            var name = ts.createIdentifier(ts.idText(propertyName));
+            return ts.createPropertyAccess(value, name);
+        }
+    }
+    /**
+     * Ensures that there exists a declared identifier whose value holds the given expression.
+     * This function is useful to ensure that the expression's value can be read from in subsequent expressions.
+     * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
+     *
+     * @param flattenContext Options used to control flattening.
+     * @param value the expression whose value needs to be bound.
+     * @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
+     * false if it is necessary to always emit an identifier.
+     * @param location The location to use for source maps and comments.
+     */
+    function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
+        if (ts.isIdentifier(value) && reuseIdentifierExpressions) {
+            return value;
+        }
+        else {
+            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
+            if (flattenContext.hoistTempVariables) {
+                flattenContext.context.hoistVariableDeclaration(temp);
+                flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location));
+            }
+            else {
+                flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
+            }
+            return temp;
+        }
+    }
+    function makeArrayBindingPattern(elements) {
+        ts.Debug.assertEachNode(elements, ts.isArrayBindingElement);
+        return ts.createArrayBindingPattern(elements);
+    }
+    function makeArrayAssignmentPattern(elements) {
+        return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement));
+    }
+    function makeObjectBindingPattern(elements) {
+        ts.Debug.assertEachNode(elements, ts.isBindingElement);
+        return ts.createObjectBindingPattern(elements);
+    }
+    function makeObjectAssignmentPattern(elements) {
+        return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement));
+    }
+    function makeBindingElement(name) {
+        return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
+    }
+    function makeAssignmentElement(name) {
+        return name;
+    }
+    var restHelper = {
+        name: "typescript:rest",
+        scoped: false,
+        text: "\n            var __rest = (this && this.__rest) || function (s, e) {\n                var t = {};\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n                    t[p] = s[p];\n                if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n                    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\n                        t[p[i]] = s[p[i]];\n                return t;\n            };"
+    };
+    /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
+     * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
+     */
+    function createRestCall(context, value, elements, computedTempVariables, location) {
+        context.requestEmitHelper(restHelper);
+        var propertyNames = [];
+        var computedTempVariableOffset = 0;
+        for (var i = 0; i < elements.length - 1; i++) {
+            var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]);
+            if (propertyName) {
+                if (ts.isComputedPropertyName(propertyName)) {
+                    var temp = computedTempVariables[computedTempVariableOffset];
+                    computedTempVariableOffset++;
+                    // typeof _tmp === "symbol" ? _tmp : _tmp + ""
+                    propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral(""))));
+                }
+                else {
+                    propertyNames.push(ts.createLiteral(propertyName));
+                }
+            }
+        }
+        return ts.createCall(ts.getHelperName("__rest"), 
+        /*typeArguments*/ undefined, [
+            value,
+            ts.setTextRange(ts.createArrayLiteral(propertyNames), location)
+        ]);
+    }
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/// <reference path="./destructuring.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    /**
+     * Indicates whether to emit type metadata in the new format.
+     */
+    var USE_NEW_TYPE_METADATA_FORMAT = false;
+    var TypeScriptSubstitutionFlags;
+    (function (TypeScriptSubstitutionFlags) {
+        /** Enables substitutions for decorated classes. */
+        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
+        /** Enables substitutions for namespace exports. */
+        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports";
+        /* Enables substitutions for unqualified enum members */
+        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers";
+    })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {}));
+    var ClassFacts;
+    (function (ClassFacts) {
+        ClassFacts[ClassFacts["None"] = 0] = "None";
+        ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties";
+        ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators";
+        ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators";
+        ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace";
+        ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport";
+        ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport";
+        ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass";
+        ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression";
+        ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators";
+        ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName";
+        ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression";
+        ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported";
+    })(ClassFacts || (ClassFacts = {}));
+    function transformTypeScript(context) {
+        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var resolver = context.getEmitResolver();
+        var compilerOptions = context.getCompilerOptions();
+        var strictNullChecks = typeof compilerOptions.strictNullChecks === "undefined" ? compilerOptions.strict : compilerOptions.strictNullChecks;
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var moduleKind = ts.getEmitModuleKind(compilerOptions);
+        // Save the previous transformation hooks.
+        var previousOnEmitNode = context.onEmitNode;
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        // Set new transformation hooks.
+        context.onEmitNode = onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        // Enable substitution for property/element access to emit const enum values.
+        context.enableSubstitution(179 /* PropertyAccessExpression */);
+        context.enableSubstitution(180 /* ElementAccessExpression */);
+        // These variables contain state that changes as we descend into the tree.
+        var currentSourceFile;
+        var currentNamespace;
+        var currentNamespaceContainerName;
+        var currentScope;
+        var currentScopeFirstDeclarationsOfName;
+        /**
+         * Keeps track of whether expression substitution has been enabled for specific edge cases.
+         * They are persisted between each SourceFile transformation and should not be reset.
+         */
+        var enabledSubstitutions;
+        /**
+         * A map that keeps track of aliases created for classes with decorators to avoid issues
+         * with the double-binding behavior of classes.
+         */
+        var classAliases;
+        /**
+         * Keeps track of whether  we are within any containing namespaces when performing
+         * just-in-time substitution while printing an expression identifier.
+         */
+        var applicableSubstitutions;
+        return transformSourceFile;
+        /**
+         * Transform TypeScript-specific syntax in a SourceFile.
+         *
+         * @param node A SourceFile node.
+         */
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            currentSourceFile = node;
+            var visited = saveStateAndInvoke(node, visitSourceFile);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            currentSourceFile = undefined;
+            return visited;
+        }
+        /**
+         * Visits a node, saving and restoring state variables on the stack.
+         *
+         * @param node The node to visit.
+         */
+        function saveStateAndInvoke(node, f) {
+            // Save state
+            var savedCurrentScope = currentScope;
+            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
+            // Handle state changes before visiting a node.
+            onBeforeVisitNode(node);
+            var visited = f(node);
+            // Restore state
+            if (currentScope !== savedCurrentScope) {
+                currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
+            }
+            currentScope = savedCurrentScope;
+            return visited;
+        }
+        /**
+         * Performs actions that should always occur immediately before visiting a node.
+         *
+         * @param node The node to visit.
+         */
+        function onBeforeVisitNode(node) {
+            switch (node.kind) {
+                case 265 /* SourceFile */:
+                case 235 /* CaseBlock */:
+                case 234 /* ModuleBlock */:
+                case 207 /* Block */:
+                    currentScope = node;
+                    currentScopeFirstDeclarationsOfName = undefined;
+                    break;
+                case 229 /* ClassDeclaration */:
+                case 228 /* FunctionDeclaration */:
+                    if (ts.hasModifier(node, 2 /* Ambient */)) {
+                        break;
+                    }
+                    // Record these declarations provided that they have a name.
+                    if (node.name) {
+                        recordEmittedDeclarationInScope(node);
+                    }
+                    else {
+                        // These nodes should always have names unless they are default-exports;
+                        // however, class declaration parsing allows for undefined names, so syntactically invalid
+                        // programs may also have an undefined name.
+                        ts.Debug.assert(node.kind === 229 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */));
+                    }
+                    break;
+            }
+        }
+        /**
+         * General-purpose node visitor.
+         *
+         * @param node The node to visit.
+         */
+        function visitor(node) {
+            return saveStateAndInvoke(node, visitorWorker);
+        }
+        /**
+         * Visits and possibly transforms any node.
+         *
+         * @param node The node to visit.
+         */
+        function visitorWorker(node) {
+            if (node.transformFlags & 1 /* TypeScript */) {
+                // This node is explicitly marked as TypeScript, so we should transform the node.
+                return visitTypeScript(node);
+            }
+            else if (node.transformFlags & 2 /* ContainsTypeScript */) {
+                // This node contains TypeScript, so we should visit its children.
+                return ts.visitEachChild(node, visitor, context);
+            }
+            return node;
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a SourceFile.
+         *
+         * @param node The node to visit.
+         */
+        function sourceElementVisitor(node) {
+            return saveStateAndInvoke(node, sourceElementVisitorWorker);
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a SourceFile.
+         *
+         * @param node The node to visit.
+         */
+        function sourceElementVisitorWorker(node) {
+            switch (node.kind) {
+                case 238 /* ImportDeclaration */:
+                case 237 /* ImportEqualsDeclaration */:
+                case 243 /* ExportAssignment */:
+                case 244 /* ExportDeclaration */:
+                    return visitEllidableStatement(node);
+                default:
+                    return visitorWorker(node);
+            }
+        }
+        function visitEllidableStatement(node) {
+            var parsed = ts.getParseTreeNode(node);
+            if (parsed !== node) {
+                // If the node has been transformed by a `before` transformer, perform no ellision on it
+                // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
+                return node;
+            }
+            switch (node.kind) {
+                case 238 /* ImportDeclaration */:
+                    return visitImportDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return visitImportEqualsDeclaration(node);
+                case 243 /* ExportAssignment */:
+                    return visitExportAssignment(node);
+                case 244 /* ExportDeclaration */:
+                    return visitExportDeclaration(node);
+                default:
+                    ts.Debug.fail("Unhandled ellided statement");
+            }
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a namespace.
+         *
+         * @param node The node to visit.
+         */
+        function namespaceElementVisitor(node) {
+            return saveStateAndInvoke(node, namespaceElementVisitorWorker);
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a namespace.
+         *
+         * @param node The node to visit.
+         */
+        function namespaceElementVisitorWorker(node) {
+            if (node.kind === 244 /* ExportDeclaration */ ||
+                node.kind === 238 /* ImportDeclaration */ ||
+                node.kind === 239 /* ImportClause */ ||
+                (node.kind === 237 /* ImportEqualsDeclaration */ &&
+                    node.moduleReference.kind === 248 /* ExternalModuleReference */)) {
+                // do not emit ES6 imports and exports since they are illegal inside a namespace
+                return undefined;
+            }
+            else if (node.transformFlags & 1 /* TypeScript */ || ts.hasModifier(node, 1 /* Export */)) {
+                // This node is explicitly marked as TypeScript, or is exported at the namespace
+                // level, so we should transform the node.
+                return visitTypeScript(node);
+            }
+            else if (node.transformFlags & 2 /* ContainsTypeScript */) {
+                // This node contains TypeScript, so we should visit its children.
+                return ts.visitEachChild(node, visitor, context);
+            }
+            return node;
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
+         *
+         * @param node The node to visit.
+         */
+        function classElementVisitor(node) {
+            return saveStateAndInvoke(node, classElementVisitorWorker);
+        }
+        /**
+         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
+         *
+         * @param node The node to visit.
+         */
+        function classElementVisitorWorker(node) {
+            switch (node.kind) {
+                case 152 /* Constructor */:
+                    // TypeScript constructors are transformed in `visitClassDeclaration`.
+                    // We elide them here as `visitorWorker` checks transform flags, which could
+                    // erronously include an ES6 constructor without TypeScript syntax.
+                    return undefined;
+                case 149 /* PropertyDeclaration */:
+                case 157 /* IndexSignature */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 151 /* MethodDeclaration */:
+                    // Fallback to the default visit behavior.
+                    return visitorWorker(node);
+                case 206 /* SemicolonClassElement */:
+                    return node;
+                default:
+                    ts.Debug.failBadSyntaxKind(node);
+                    return undefined;
+            }
+        }
+        function modifierVisitor(node) {
+            if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) {
+                return undefined;
+            }
+            else if (currentNamespace && node.kind === 84 /* ExportKeyword */) {
+                return undefined;
+            }
+            return node;
+        }
+        /**
+         * Branching visitor, visits a TypeScript syntax node.
+         *
+         * @param node The node to visit.
+         */
+        function visitTypeScript(node) {
+            if (ts.hasModifier(node, 2 /* Ambient */) && ts.isStatement(node)) {
+                // TypeScript ambient declarations are elided, but some comments may be preserved.
+                // See the implementation of `getLeadingComments` in comments.ts for more details.
+                return ts.createNotEmittedStatement(node);
+            }
+            switch (node.kind) {
+                case 84 /* ExportKeyword */:
+                case 79 /* DefaultKeyword */:
+                    // ES6 export and default modifiers are elided when inside a namespace.
+                    return currentNamespace ? undefined : node;
+                case 114 /* PublicKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 117 /* AbstractKeyword */:
+                case 76 /* ConstKeyword */:
+                case 124 /* DeclareKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                // TypeScript accessibility and readonly modifiers are elided.
+                case 164 /* ArrayType */:
+                case 165 /* TupleType */:
+                case 163 /* TypeLiteral */:
+                case 158 /* TypePredicate */:
+                case 145 /* TypeParameter */:
+                case 119 /* AnyKeyword */:
+                case 122 /* BooleanKeyword */:
+                case 136 /* StringKeyword */:
+                case 133 /* NumberKeyword */:
+                case 130 /* NeverKeyword */:
+                case 105 /* VoidKeyword */:
+                case 137 /* SymbolKeyword */:
+                case 161 /* ConstructorType */:
+                case 160 /* FunctionType */:
+                case 162 /* TypeQuery */:
+                case 159 /* TypeReference */:
+                case 166 /* UnionType */:
+                case 167 /* IntersectionType */:
+                case 168 /* ParenthesizedType */:
+                case 169 /* ThisType */:
+                case 170 /* TypeOperator */:
+                case 171 /* IndexedAccessType */:
+                case 172 /* MappedType */:
+                case 173 /* LiteralType */:
+                // TypeScript type nodes are elided.
+                case 157 /* IndexSignature */:
+                // TypeScript index signatures are elided.
+                case 147 /* Decorator */:
+                // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration.
+                case 231 /* TypeAliasDeclaration */:
+                // TypeScript type-only declarations are elided.
+                case 149 /* PropertyDeclaration */:
+                // TypeScript property declarations are elided.
+                case 236 /* NamespaceExportDeclaration */:
+                    // TypeScript namespace export declarations are elided.
+                    return undefined;
+                case 152 /* Constructor */:
+                    return visitConstructor(node);
+                case 230 /* InterfaceDeclaration */:
+                    // TypeScript interfaces are elided, but some comments may be preserved.
+                    // See the implementation of `getLeadingComments` in comments.ts for more details.
+                    return ts.createNotEmittedStatement(node);
+                case 229 /* ClassDeclaration */:
+                    // This is a class declaration with TypeScript syntax extensions.
+                    //
+                    // TypeScript class syntax extensions include:
+                    // - decorators
+                    // - optional `implements` heritage clause
+                    // - parameter property assignments in the constructor
+                    // - property declarations
+                    // - index signatures
+                    // - method overload signatures
+                    return visitClassDeclaration(node);
+                case 199 /* ClassExpression */:
+                    // This is a class expression with TypeScript syntax extensions.
+                    //
+                    // TypeScript class syntax extensions include:
+                    // - decorators
+                    // - optional `implements` heritage clause
+                    // - parameter property assignments in the constructor
+                    // - property declarations
+                    // - index signatures
+                    // - method overload signatures
+                    return visitClassExpression(node);
+                case 259 /* HeritageClause */:
+                    // This is a heritage clause with TypeScript syntax extensions.
+                    //
+                    // TypeScript heritage clause extensions include:
+                    // - `implements` clause
+                    return visitHeritageClause(node);
+                case 201 /* ExpressionWithTypeArguments */:
+                    // TypeScript supports type arguments on an expression in an `extends` heritage clause.
+                    return visitExpressionWithTypeArguments(node);
+                case 151 /* MethodDeclaration */:
+                    // TypeScript method declarations may have decorators, modifiers
+                    // or type annotations.
+                    return visitMethodDeclaration(node);
+                case 153 /* GetAccessor */:
+                    // Get Accessors can have TypeScript modifiers, decorators, and type annotations.
+                    return visitGetAccessor(node);
+                case 154 /* SetAccessor */:
+                    // Set Accessors can have TypeScript modifiers and type annotations.
+                    return visitSetAccessor(node);
+                case 228 /* FunctionDeclaration */:
+                    // Typescript function declarations can have modifiers, decorators, and type annotations.
+                    return visitFunctionDeclaration(node);
+                case 186 /* FunctionExpression */:
+                    // TypeScript function expressions can have modifiers and type annotations.
+                    return visitFunctionExpression(node);
+                case 187 /* ArrowFunction */:
+                    // TypeScript arrow functions can have modifiers and type annotations.
+                    return visitArrowFunction(node);
+                case 146 /* Parameter */:
+                    // This is a parameter declaration with TypeScript syntax extensions.
+                    //
+                    // TypeScript parameter declaration syntax extensions include:
+                    // - decorators
+                    // - accessibility modifiers
+                    // - the question mark (?) token for optional parameters
+                    // - type annotations
+                    // - this parameters
+                    return visitParameter(node);
+                case 185 /* ParenthesizedExpression */:
+                    // ParenthesizedExpressions are TypeScript if their expression is a
+                    // TypeAssertion or AsExpression
+                    return visitParenthesizedExpression(node);
+                case 184 /* TypeAssertionExpression */:
+                case 202 /* AsExpression */:
+                    // TypeScript type assertions are removed, but their subtrees are preserved.
+                    return visitAssertionExpression(node);
+                case 181 /* CallExpression */:
+                    return visitCallExpression(node);
+                case 182 /* NewExpression */:
+                    return visitNewExpression(node);
+                case 203 /* NonNullExpression */:
+                    // TypeScript non-null expressions are removed, but their subtrees are preserved.
+                    return visitNonNullExpression(node);
+                case 232 /* EnumDeclaration */:
+                    // TypeScript enum declarations do not exist in ES6 and must be rewritten.
+                    return visitEnumDeclaration(node);
+                case 208 /* VariableStatement */:
+                    // TypeScript namespace exports for variable statements must be transformed.
+                    return visitVariableStatement(node);
+                case 226 /* VariableDeclaration */:
+                    return visitVariableDeclaration(node);
+                case 233 /* ModuleDeclaration */:
+                    // TypeScript namespace declarations must be transformed.
+                    return visitModuleDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    // TypeScript namespace or external module import.
+                    return visitImportEqualsDeclaration(node);
+                default:
+                    ts.Debug.failBadSyntaxKind(node);
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function visitSourceFile(node) {
+            var alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
+                !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015);
+            return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
+        }
+        /**
+         * Tests whether we should emit a __decorate call for a class declaration.
+         */
+        function shouldEmitDecorateCallForClass(node) {
+            if (node.decorators && node.decorators.length > 0) {
+                return true;
+            }
+            var constructor = ts.getFirstConstructorWithBody(node);
+            if (constructor) {
+                return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
+            }
+            return false;
+        }
+        /**
+         * Tests whether we should emit a __decorate call for a parameter declaration.
+         */
+        function shouldEmitDecorateCallForParameter(parameter) {
+            return parameter.decorators !== undefined && parameter.decorators.length > 0;
+        }
+        function getClassFacts(node, staticProperties) {
+            var facts = 0 /* None */;
+            if (ts.some(staticProperties))
+                facts |= 1 /* HasStaticInitializedProperties */;
+            var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node);
+            if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */)
+                facts |= 64 /* IsDerivedClass */;
+            if (shouldEmitDecorateCallForClass(node))
+                facts |= 2 /* HasConstructorDecorators */;
+            if (ts.childIsDecorated(node))
+                facts |= 4 /* HasMemberDecorators */;
+            if (isExportOfNamespace(node))
+                facts |= 8 /* IsExportOfNamespace */;
+            else if (isDefaultExternalModuleExport(node))
+                facts |= 32 /* IsDefaultExternalExport */;
+            else if (isNamedExternalModuleExport(node))
+                facts |= 16 /* IsNamedExternalExport */;
+            if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */))
+                facts |= 128 /* UseImmediatelyInvokedFunctionExpression */;
+            return facts;
+        }
+        /**
+         * Transforms a class declaration with TypeScript syntax into compatible ES6.
+         *
+         * This function will only be called when one of the following conditions are met:
+         * - The class has decorators.
+         * - The class has property declarations with initializers.
+         * - The class contains a constructor that contains parameters with accessibility modifiers.
+         * - The class is an export in a TypeScript namespace.
+         *
+         * @param node The node to transform.
+         */
+        function visitClassDeclaration(node) {
+            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
+            var facts = getClassFacts(node, staticProperties);
+            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
+                context.startLexicalEnvironment();
+            }
+            var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined);
+            var classStatement = facts & 2 /* HasConstructorDecorators */
+                ? createClassDeclarationHeadWithDecorators(node, name, facts)
+                : createClassDeclarationHeadWithoutDecorators(node, name, facts);
+            var statements = [classStatement];
+            // Emit static property assignment. Because classDeclaration is lexically evaluated,
+            // it is safe to emit static property assignment after classDeclaration
+            // From ES6 specification:
+            //      HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
+            //                                  a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
+            if (facts & 1 /* HasStaticInitializedProperties */) {
+                addInitializedPropertyStatements(statements, staticProperties, facts & 128 /* UseImmediatelyInvokedFunctionExpression */ ? ts.getInternalName(node) : ts.getLocalName(node));
+            }
+            // Write any decorators of the node.
+            addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
+            addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
+            addConstructorDecorationStatement(statements, node);
+            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
+                // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the
+                // 'es2015' transformer can properly nest static initializers and decorators. The result
+                // looks something like:
+                //
+                //  var C = function () {
+                //      class C {
+                //      }
+                //      C.static_prop = 1;
+                //      return C;
+                //  }();
+                //
+                var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 18 /* CloseBraceToken */);
+                var localName = ts.getInternalName(node);
+                // The following partially-emitted expression exists purely to align our sourcemap
+                // emit with the original emitter.
+                var outer = ts.createPartiallyEmittedExpression(localName);
+                outer.end = closingBraceLocation.end;
+                ts.setEmitFlags(outer, 1536 /* NoComments */);
+                var statement = ts.createReturn(outer);
+                statement.pos = closingBraceLocation.pos;
+                ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
+                statements.push(statement);
+                ts.addRange(statements, context.endLexicalEnvironment());
+                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
+                ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */);
+                var varStatement = ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                    ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), 
+                    /*type*/ undefined, iife)
+                ]));
+                ts.setOriginalNode(varStatement, node);
+                ts.setCommentRange(varStatement, node);
+                ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node));
+                ts.startOnNewLine(varStatement);
+                statements = [varStatement];
+            }
+            // If the class is exported as part of a TypeScript namespace, emit the namespace export.
+            // Otherwise, if the class was exported at the top level and was decorated, emit an export
+            // declaration or export default for the class.
+            if (facts & 8 /* IsExportOfNamespace */) {
+                addExportMemberAssignment(statements, node);
+            }
+            else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) {
+                if (facts & 32 /* IsDefaultExternalExport */) {
+                    statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
+                }
+                else if (facts & 16 /* IsNamedExternalExport */) {
+                    statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
+                }
+            }
+            if (statements.length > 1) {
+                // Add a DeclarationMarker as a marker for the end of the declaration
+                statements.push(ts.createEndOfDeclarationMarker(node));
+                ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Transforms a non-decorated class declaration and appends the resulting statements.
+         *
+         * @param node A ClassDeclaration node.
+         * @param name The name of the class.
+         * @param facts Precomputed facts about the class.
+         */
+        function createClassDeclarationHeadWithoutDecorators(node, name, facts) {
+            //  ${modifiers} class ${name} ${heritageClauses} {
+            //      ${members}
+            //  }
+            // we do not emit modifiers on the declaration if we are emitting an IIFE
+            var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */)
+                ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)
+                : undefined;
+            var classDeclaration = ts.createClassDeclaration(
+            /*decorators*/ undefined, modifiers, name, 
+            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0));
+            // To better align with the old emitter, we should not emit a trailing source map
+            // entry if the class has static properties.
+            var emitFlags = ts.getEmitFlags(node);
+            if (facts & 1 /* HasStaticInitializedProperties */) {
+                emitFlags |= 32 /* NoTrailingSourceMap */;
+            }
+            ts.setTextRange(classDeclaration, node);
+            ts.setOriginalNode(classDeclaration, node);
+            ts.setEmitFlags(classDeclaration, emitFlags);
+            return classDeclaration;
+        }
+        /**
+         * Transforms a decorated class declaration and appends the resulting statements. If
+         * the class requires an alias to avoid issues with double-binding, the alias is returned.
+         */
+        function createClassDeclarationHeadWithDecorators(node, name, facts) {
+            // When we emit an ES6 class that has a class decorator, we must tailor the
+            // emit to certain specific cases.
+            //
+            // In the simplest case, we emit the class declaration as a let declaration, and
+            // evaluate decorators after the close of the class body:
+            //
+            //  [Example 1]
+            //  ---------------------------------------------------------------------
+            //  TypeScript                      | Javascript
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = class C {
+            //  class C {                       | }
+            //  }                               | C = __decorate([dec], C);
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = class C {
+            //  export class C {                | }
+            //  }                               | C = __decorate([dec], C);
+            //                                  | export { C };
+            //  ---------------------------------------------------------------------
+            //
+            // If a class declaration contains a reference to itself *inside* of the class body,
+            // this introduces two bindings to the class: One outside of the class body, and one
+            // inside of the class body. If we apply decorators as in [Example 1] above, there
+            // is the possibility that the decorator `dec` will return a new value for the
+            // constructor, which would result in the binding inside of the class no longer
+            // pointing to the same reference as the binding outside of the class.
+            //
+            // As a result, we must instead rewrite all references to the class *inside* of the
+            // class body to instead point to a local temporary alias for the class:
+            //
+            //  [Example 2]
+            //  ---------------------------------------------------------------------
+            //  TypeScript                      | Javascript
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = C_1 = class C {
+            //  class C {                       |   static x() { return C_1.y; }
+            //    static x() { return C.y; }    | }
+            //    static y = 1;                 | C.y = 1;
+            //  }                               | C = C_1 = __decorate([dec], C);
+            //                                  | var C_1;
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = class C {
+            //  export class C {                |   static x() { return C_1.y; }
+            //    static x() { return C.y; }    | }
+            //    static y = 1;                 | C.y = 1;
+            //  }                               | C = C_1 = __decorate([dec], C);
+            //                                  | export { C };
+            //                                  | var C_1;
+            //  ---------------------------------------------------------------------
+            //
+            // If a class declaration is the default export of a module, we instead emit
+            // the export after the decorated declaration:
+            //
+            //  [Example 3]
+            //  ---------------------------------------------------------------------
+            //  TypeScript                      | Javascript
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let default_1 = class {
+            //  export default class {          | }
+            //  }                               | default_1 = __decorate([dec], default_1);
+            //                                  | export default default_1;
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = class C {
+            //  export default class C {        | }
+            //  }                               | C = __decorate([dec], C);
+            //                                  | export default C;
+            //  ---------------------------------------------------------------------
+            //
+            // If the class declaration is the default export and a reference to itself
+            // inside of the class body, we must emit both an alias for the class *and*
+            // move the export after the declaration:
+            //
+            //  [Example 4]
+            //  ---------------------------------------------------------------------
+            //  TypeScript                      | Javascript
+            //  ---------------------------------------------------------------------
+            //  @dec                            | let C = class C {
+            //  export default class C {        |   static x() { return C_1.y; }
+            //    static x() { return C.y; }    | }
+            //    static y = 1;                 | C.y = 1;
+            //  }                               | C = C_1 = __decorate([dec], C);
+            //                                  | export default C;
+            //                                  | var C_1;
+            //  ---------------------------------------------------------------------
+            //
+            var location = ts.moveRangePastDecorators(node);
+            var classAlias = getClassAliasIfNeeded(node);
+            var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+            //  ... = class ${name} ${heritageClauses} {
+            //      ${members}
+            //  }
+            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
+            var members = transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0);
+            var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
+            ts.setOriginalNode(classExpression, node);
+            ts.setTextRange(classExpression, location);
+            //  let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
+            //                                         or decoratedClassAlias if the class contain self-reference.
+            var statement = ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(declName, 
+                /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression)
+            ], 1 /* Let */));
+            ts.setOriginalNode(statement, node);
+            ts.setTextRange(statement, location);
+            ts.setCommentRange(statement, node);
+            return statement;
+        }
+        /**
+         * Transforms a class expression with TypeScript syntax into compatible ES6.
+         *
+         * This function will only be called when one of the following conditions are met:
+         * - The class has property declarations with initializers.
+         * - The class contains a constructor that contains parameters with accessibility modifiers.
+         *
+         * @param node The node to transform.
+         */
+        function visitClassExpression(node) {
+            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
+            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
+            var members = transformClassMembers(node, ts.some(heritageClauses, function (c) { return c.token === 85 /* ExtendsKeyword */; }));
+            var classExpression = ts.createClassExpression(
+            /*modifiers*/ undefined, node.name, 
+            /*typeParameters*/ undefined, heritageClauses, members);
+            ts.setOriginalNode(classExpression, node);
+            ts.setTextRange(classExpression, node);
+            if (staticProperties.length > 0) {
+                var expressions = [];
+                var temp = ts.createTempVariable(hoistVariableDeclaration);
+                if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) {
+                    // record an alias as the class name is not in scope for statics.
+                    enableSubstitutionForClassAliases();
+                    classAliases[ts.getOriginalNodeId(node)] = ts.getSynthesizedClone(temp);
+                }
+                // To preserve the behavior of the old emitter, we explicitly indent
+                // the body of a class with static initializers.
+                ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression));
+                expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression)));
+                ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
+                expressions.push(ts.startOnNewLine(temp));
+                return ts.inlineExpressions(expressions);
+            }
+            return classExpression;
+        }
+        /**
+         * Transforms the members of a class.
+         *
+         * @param node The current class.
+         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
+         */
+        function transformClassMembers(node, isDerivedClass) {
+            var members = [];
+            var constructor = transformConstructor(node, isDerivedClass);
+            if (constructor) {
+                members.push(constructor);
+            }
+            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
+            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
+        }
+        /**
+         * Transforms (or creates) a constructor for a class.
+         *
+         * @param node The current class.
+         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
+         */
+        function transformConstructor(node, isDerivedClass) {
+            // Check if we have property assignment inside class declaration.
+            // If there is a property assignment, we need to emit constructor whether users define it or not
+            // If there is no property assignment, we can omit constructor if users do not define it
+            var hasInstancePropertyWithInitializer = ts.forEach(node.members, isInstanceInitializedProperty);
+            var hasParameterPropertyAssignments = node.transformFlags & 262144 /* ContainsParameterPropertyAssignments */;
+            var constructor = ts.getFirstConstructorWithBody(node);
+            // If the class does not contain nodes that require a synthesized constructor,
+            // accept the current constructor if it exists.
+            if (!hasInstancePropertyWithInitializer && !hasParameterPropertyAssignments) {
+                return ts.visitEachChild(constructor, visitor, context);
+            }
+            var parameters = transformConstructorParameters(constructor);
+            var body = transformConstructorBody(node, constructor, isDerivedClass);
+            //  constructor(${parameters}) {
+            //      ${body}
+            //  }
+            return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor(
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, parameters, body), constructor || node), constructor));
+        }
+        /**
+         * Transforms (or creates) the parameters for the constructor of a class with
+         * parameter property assignments or instance property initializers.
+         *
+         * @param constructor The constructor declaration.
+         */
+        function transformConstructorParameters(constructor) {
+            // The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
+            // If constructor is empty, then
+            //     If ClassHeritag_eopt is present and protoParent is not null, then
+            //          Let constructor be the result of parsing the source text
+            //              constructor(...args) { super (...args);}
+            //          using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
+            //      Else,
+            //           Let constructor be the result of parsing the source text
+            //               constructor( ){ }
+            //           using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
+            //
+            // While we could emit the '...args' rest parameter, certain later tools in the pipeline might
+            // downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
+            // Instead, we'll avoid using a rest parameter and spread into the super call as
+            // 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
+            return ts.visitParameterList(constructor && constructor.parameters, visitor, context)
+                || [];
+        }
+        /**
+         * Transforms (or creates) a constructor body for a class with parameter property
+         * assignments or instance property initializers.
+         *
+         * @param node The current class.
+         * @param constructor The current class constructor.
+         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
+         */
+        function transformConstructorBody(node, constructor, isDerivedClass) {
+            var statements = [];
+            var indexOfFirstStatement = 0;
+            resumeLexicalEnvironment();
+            if (constructor) {
+                indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements);
+                // Add parameters with property assignments. Transforms this:
+                //
+                //  constructor (public x, public y) {
+                //  }
+                //
+                // Into this:
+                //
+                //  constructor (x, y) {
+                //      this.x = x;
+                //      this.y = y;
+                //  }
+                //
+                var propertyAssignments = getParametersWithPropertyAssignments(constructor);
+                ts.addRange(statements, ts.map(propertyAssignments, transformParameterWithPropertyAssignment));
+            }
+            else if (isDerivedClass) {
+                // Add a synthetic `super` call:
+                //
+                //  super(...arguments);
+                //
+                statements.push(ts.createStatement(ts.createCall(ts.createSuper(), 
+                /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))])));
+            }
+            // Add the property initializers. Transforms this:
+            //
+            //  public x = 1;
+            //
+            // Into this:
+            //
+            //  constructor() {
+            //      this.x = 1;
+            //  }
+            //
+            var properties = getInitializedProperties(node, /*isStatic*/ false);
+            addInitializedPropertyStatements(statements, properties, ts.createThis());
+            if (constructor) {
+                // The class already had a constructor, so we should add the existing statements, skipping the initial super call.
+                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement));
+            }
+            // End the lexical environment.
+            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
+            return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
+            /*location*/ constructor ? constructor.body.statements : node.members), 
+            /*multiLine*/ true), 
+            /*location*/ constructor ? constructor.body : undefined);
+        }
+        /**
+         * Adds super call and preceding prologue directives into the list of statements.
+         *
+         * @param ctor The constructor node.
+         * @returns index of the statement that follows super call
+         */
+        function addPrologueDirectivesAndInitialSuperCall(ctor, result) {
+            if (ctor.body) {
+                var statements = ctor.body.statements;
+                // add prologue directives to the list (if any)
+                var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
+                if (index === statements.length) {
+                    // list contains nothing but prologue directives (or empty) - exit
+                    return index;
+                }
+                var statement = statements[index];
+                if (statement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
+                    result.push(ts.visitNode(statement, visitor, ts.isStatement));
+                    return index + 1;
+                }
+                return index;
+            }
+            return 0;
+        }
+        /**
+         * Gets all parameters of a constructor that should be transformed into property assignments.
+         *
+         * @param node The constructor node.
+         */
+        function getParametersWithPropertyAssignments(node) {
+            return ts.filter(node.parameters, isParameterWithPropertyAssignment);
+        }
+        /**
+         * Determines whether a parameter should be transformed into a property assignment.
+         *
+         * @param parameter The parameter node.
+         */
+        function isParameterWithPropertyAssignment(parameter) {
+            return ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */)
+                && ts.isIdentifier(parameter.name);
+        }
+        /**
+         * Transforms a parameter into a property assignment statement.
+         *
+         * @param node The parameter declaration.
+         */
+        function transformParameterWithPropertyAssignment(node) {
+            ts.Debug.assert(ts.isIdentifier(node.name));
+            var name = node.name;
+            var propertyName = ts.getMutableClone(name);
+            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */);
+            var localName = ts.getMutableClone(name);
+            ts.setEmitFlags(localName, 1536 /* NoComments */);
+            return ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), ts.moveRangePos(node, -1)));
+        }
+        /**
+         * Gets all property declarations with initializers on either the static or instance side of a class.
+         *
+         * @param node The class node.
+         * @param isStatic A value indicating whether to get properties from the static or instance side of the class.
+         */
+        function getInitializedProperties(node, isStatic) {
+            return ts.filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
+        }
+        /**
+         * Gets a value indicating whether a class element is a static property declaration with an initializer.
+         *
+         * @param member The class element node.
+         */
+        function isStaticInitializedProperty(member) {
+            return isInitializedProperty(member, /*isStatic*/ true);
+        }
+        /**
+         * Gets a value indicating whether a class element is an instance property declaration with an initializer.
+         *
+         * @param member The class element node.
+         */
+        function isInstanceInitializedProperty(member) {
+            return isInitializedProperty(member, /*isStatic*/ false);
+        }
+        /**
+         * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
+         *
+         * @param member The class element node.
+         * @param isStatic A value indicating whether the member should be a static or instance member.
+         */
+        function isInitializedProperty(member, isStatic) {
+            return member.kind === 149 /* PropertyDeclaration */
+                && isStatic === ts.hasModifier(member, 32 /* Static */)
+                && member.initializer !== undefined;
+        }
+        /**
+         * Generates assignment statements for property initializers.
+         *
+         * @param properties An array of property declarations to transform.
+         * @param receiver The receiver on which each property should be assigned.
+         */
+        function addInitializedPropertyStatements(statements, properties, receiver) {
+            for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) {
+                var property = properties_10[_i];
+                var statement = ts.createStatement(transformInitializedProperty(property, receiver));
+                ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property));
+                ts.setCommentRange(statement, property);
+                statements.push(statement);
+            }
+        }
+        /**
+         * Generates assignment expressions for property initializers.
+         *
+         * @param properties An array of property declarations to transform.
+         * @param receiver The receiver on which each property should be assigned.
+         */
+        function generateInitializedPropertyExpressions(properties, receiver) {
+            var expressions = [];
+            for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) {
+                var property = properties_11[_i];
+                var expression = transformInitializedProperty(property, receiver);
+                expression.startsOnNewLine = true;
+                ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property));
+                ts.setCommentRange(expression, property);
+                expressions.push(expression);
+            }
+            return expressions;
+        }
+        /**
+         * Transforms a property initializer into an assignment statement.
+         *
+         * @param property The property declaration.
+         * @param receiver The object receiving the property assignment.
+         */
+        function transformInitializedProperty(property, receiver) {
+            var propertyName = visitPropertyNameOfClassElement(property);
+            var initializer = ts.visitNode(property.initializer, visitor, ts.isExpression);
+            var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
+            return ts.createAssignment(memberAccess, initializer);
+        }
+        /**
+         * Gets either the static or instance members of a class that are decorated, or have
+         * parameters that are decorated.
+         *
+         * @param node The class containing the member.
+         * @param isStatic A value indicating whether to retrieve static or instance members of
+         *                 the class.
+         */
+        function getDecoratedClassElements(node, isStatic) {
+            return ts.filter(node.members, isStatic ? isStaticDecoratedClassElement : isInstanceDecoratedClassElement);
+        }
+        /**
+         * Determines whether a class member is a static member of a class that is decorated, or
+         * has parameters that are decorated.
+         *
+         * @param member The class member.
+         */
+        function isStaticDecoratedClassElement(member) {
+            return isDecoratedClassElement(member, /*isStatic*/ true);
+        }
+        /**
+         * Determines whether a class member is an instance member of a class that is decorated,
+         * or has parameters that are decorated.
+         *
+         * @param member The class member.
+         */
+        function isInstanceDecoratedClassElement(member) {
+            return isDecoratedClassElement(member, /*isStatic*/ false);
+        }
+        /**
+         * Determines whether a class member is either a static or an instance member of a class
+         * that is decorated, or has parameters that are decorated.
+         *
+         * @param member The class member.
+         */
+        function isDecoratedClassElement(member, isStatic) {
+            return ts.nodeOrChildIsDecorated(member)
+                && isStatic === ts.hasModifier(member, 32 /* Static */);
+        }
+        /**
+         * Gets an array of arrays of decorators for the parameters of a function-like node.
+         * The offset into the result array should correspond to the offset of the parameter.
+         *
+         * @param node The function-like node.
+         */
+        function getDecoratorsOfParameters(node) {
+            var decorators;
+            if (node) {
+                var parameters = node.parameters;
+                for (var i = 0; i < parameters.length; i++) {
+                    var parameter = parameters[i];
+                    if (decorators || parameter.decorators) {
+                        if (!decorators) {
+                            decorators = new Array(parameters.length);
+                        }
+                        decorators[i] = parameter.decorators;
+                    }
+                }
+            }
+            return decorators;
+        }
+        /**
+         * Gets an AllDecorators object containing the decorators for the class and the decorators for the
+         * parameters of the constructor of the class.
+         *
+         * @param node The class node.
+         */
+        function getAllDecoratorsOfConstructor(node) {
+            var decorators = node.decorators;
+            var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node));
+            if (!decorators && !parameters) {
+                return undefined;
+            }
+            return {
+                decorators: decorators,
+                parameters: parameters
+            };
+        }
+        /**
+         * Gets an AllDecorators object containing the decorators for the member and its parameters.
+         *
+         * @param node The class node that contains the member.
+         * @param member The class member.
+         */
+        function getAllDecoratorsOfClassElement(node, member) {
+            switch (member.kind) {
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return getAllDecoratorsOfAccessors(node, member);
+                case 151 /* MethodDeclaration */:
+                    return getAllDecoratorsOfMethod(member);
+                case 149 /* PropertyDeclaration */:
+                    return getAllDecoratorsOfProperty(member);
+                default:
+                    return undefined;
+            }
+        }
+        /**
+         * Gets an AllDecorators object containing the decorators for the accessor and its parameters.
+         *
+         * @param node The class node that contains the accessor.
+         * @param accessor The class accessor member.
+         */
+        function getAllDecoratorsOfAccessors(node, accessor) {
+            if (!accessor.body) {
+                return undefined;
+            }
+            var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor;
+            var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined;
+            if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
+                return undefined;
+            }
+            var decorators = firstAccessorWithDecorators.decorators;
+            var parameters = getDecoratorsOfParameters(setAccessor);
+            if (!decorators && !parameters) {
+                return undefined;
+            }
+            return { decorators: decorators, parameters: parameters };
+        }
+        /**
+         * Gets an AllDecorators object containing the decorators for the method and its parameters.
+         *
+         * @param method The class method member.
+         */
+        function getAllDecoratorsOfMethod(method) {
+            if (!method.body) {
+                return undefined;
+            }
+            var decorators = method.decorators;
+            var parameters = getDecoratorsOfParameters(method);
+            if (!decorators && !parameters) {
+                return undefined;
+            }
+            return { decorators: decorators, parameters: parameters };
+        }
+        /**
+         * Gets an AllDecorators object containing the decorators for the property.
+         *
+         * @param property The class property member.
+         */
+        function getAllDecoratorsOfProperty(property) {
+            var decorators = property.decorators;
+            if (!decorators) {
+                return undefined;
+            }
+            return { decorators: decorators };
+        }
+        /**
+         * Transforms all of the decorators for a declaration into an array of expressions.
+         *
+         * @param node The declaration node.
+         * @param allDecorators An object containing all of the decorators for the declaration.
+         */
+        function transformAllDecoratorsOfDeclaration(node, container, allDecorators) {
+            if (!allDecorators) {
+                return undefined;
+            }
+            var decoratorExpressions = [];
+            ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator));
+            ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
+            addTypeMetadata(node, container, decoratorExpressions);
+            return decoratorExpressions;
+        }
+        /**
+         * Generates statements used to apply decorators to either the static or instance members
+         * of a class.
+         *
+         * @param node The class node.
+         * @param isStatic A value indicating whether to generate statements for static or
+         *                 instance members.
+         */
+        function addClassElementDecorationStatements(statements, node, isStatic) {
+            ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement));
+        }
+        /**
+         * Generates expressions used to apply decorators to either the static or instance members
+         * of a class.
+         *
+         * @param node The class node.
+         * @param isStatic A value indicating whether to generate expressions for static or
+         *                 instance members.
+         */
+        function generateClassElementDecorationExpressions(node, isStatic) {
+            var members = getDecoratedClassElements(node, isStatic);
+            var expressions;
+            for (var _i = 0, members_3 = members; _i < members_3.length; _i++) {
+                var member = members_3[_i];
+                var expression = generateClassElementDecorationExpression(node, member);
+                if (expression) {
+                    if (!expressions) {
+                        expressions = [expression];
+                    }
+                    else {
+                        expressions.push(expression);
+                    }
+                }
+            }
+            return expressions;
+        }
+        /**
+         * Generates an expression used to evaluate class element decorators at runtime.
+         *
+         * @param node The class node that contains the member.
+         * @param member The class member.
+         */
+        function generateClassElementDecorationExpression(node, member) {
+            var allDecorators = getAllDecoratorsOfClassElement(node, member);
+            var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
+            if (!decoratorExpressions) {
+                return undefined;
+            }
+            // Emit the call to __decorate. Given the following:
+            //
+            //   class C {
+            //     @dec method(@dec2 x) {}
+            //     @dec get accessor() {}
+            //     @dec prop;
+            //   }
+            //
+            // The emit for a method is:
+            //
+            //   __decorate([
+            //       dec,
+            //       __param(0, dec2),
+            //       __metadata("design:type", Function),
+            //       __metadata("design:paramtypes", [Object]),
+            //       __metadata("design:returntype", void 0)
+            //   ], C.prototype, "method", null);
+            //
+            // The emit for an accessor is:
+            //
+            //   __decorate([
+            //       dec
+            //   ], C.prototype, "accessor", null);
+            //
+            // The emit for a property is:
+            //
+            //   __decorate([
+            //       dec
+            //   ], C.prototype, "prop");
+            //
+            var prefix = getClassMemberPrefix(node, member);
+            var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true);
+            var descriptor = languageVersion > 0 /* ES3 */
+                ? member.kind === 149 /* PropertyDeclaration */
+                    // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
+                    // should not invoke `Object.getOwnPropertyDescriptor`.
+                    ? ts.createVoidZero()
+                    // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly.
+                    // We have this extra argument here so that we can inject an explicit property descriptor at a later date.
+                    : ts.createNull()
+                : undefined;
+            var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member));
+            ts.setEmitFlags(helper, 1536 /* NoComments */);
+            return helper;
+        }
+        /**
+         * Generates a __decorate helper call for a class constructor.
+         *
+         * @param node The class node.
+         */
+        function addConstructorDecorationStatement(statements, node) {
+            var expression = generateConstructorDecorationExpression(node);
+            if (expression) {
+                statements.push(ts.setOriginalNode(ts.createStatement(expression), node));
+            }
+        }
+        /**
+         * Generates a __decorate helper call for a class constructor.
+         *
+         * @param node The class node.
+         */
+        function generateConstructorDecorationExpression(node) {
+            var allDecorators = getAllDecoratorsOfConstructor(node);
+            var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
+            if (!decoratorExpressions) {
+                return undefined;
+            }
+            var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)];
+            var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+            var decorate = createDecorateHelper(context, decoratorExpressions, localName);
+            var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate);
+            ts.setEmitFlags(expression, 1536 /* NoComments */);
+            ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node));
+            return expression;
+        }
+        /**
+         * Transforms a decorator into an expression.
+         *
+         * @param decorator The decorator node.
+         */
+        function transformDecorator(decorator) {
+            return ts.visitNode(decorator.expression, visitor, ts.isExpression);
+        }
+        /**
+         * Transforms the decorators of a parameter.
+         *
+         * @param decorators The decorators for the parameter at the provided offset.
+         * @param parameterOffset The offset of the parameter.
+         */
+        function transformDecoratorsOfParameter(decorators, parameterOffset) {
+            var expressions;
+            if (decorators) {
+                expressions = [];
+                for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) {
+                    var decorator = decorators_1[_i];
+                    var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, 
+                    /*location*/ decorator.expression);
+                    ts.setEmitFlags(helper, 1536 /* NoComments */);
+                    expressions.push(helper);
+                }
+            }
+            return expressions;
+        }
+        /**
+         * Adds optional type metadata for a declaration.
+         *
+         * @param node The declaration node.
+         * @param decoratorExpressions The destination array to which to add new decorator expressions.
+         */
+        function addTypeMetadata(node, container, decoratorExpressions) {
+            if (USE_NEW_TYPE_METADATA_FORMAT) {
+                addNewTypeMetadata(node, container, decoratorExpressions);
+            }
+            else {
+                addOldTypeMetadata(node, container, decoratorExpressions);
+            }
+        }
+        function addOldTypeMetadata(node, container, decoratorExpressions) {
+            if (compilerOptions.emitDecoratorMetadata) {
+                if (shouldAddTypeMetadata(node)) {
+                    decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
+                }
+                if (shouldAddParamTypesMetadata(node)) {
+                    decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
+                }
+                if (shouldAddReturnTypeMetadata(node)) {
+                    decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
+                }
+            }
+        }
+        function addNewTypeMetadata(node, container, decoratorExpressions) {
+            if (compilerOptions.emitDecoratorMetadata) {
+                var properties = void 0;
+                if (shouldAddTypeMetadata(node)) {
+                    (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeTypeOfNode(node))));
+                }
+                if (shouldAddParamTypesMetadata(node)) {
+                    (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container))));
+                }
+                if (shouldAddReturnTypeMetadata(node)) {
+                    (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node))));
+                }
+                if (properties) {
+                    decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true)));
+                }
+            }
+        }
+        /**
+         * Determines whether to emit the "design:type" metadata based on the node's kind.
+         * The caller should have already tested whether the node has decorators and whether the
+         * emitDecoratorMetadata compiler option is set.
+         *
+         * @param node The node to test.
+         */
+        function shouldAddTypeMetadata(node) {
+            var kind = node.kind;
+            return kind === 151 /* MethodDeclaration */
+                || kind === 153 /* GetAccessor */
+                || kind === 154 /* SetAccessor */
+                || kind === 149 /* PropertyDeclaration */;
+        }
+        /**
+         * Determines whether to emit the "design:returntype" metadata based on the node's kind.
+         * The caller should have already tested whether the node has decorators and whether the
+         * emitDecoratorMetadata compiler option is set.
+         *
+         * @param node The node to test.
+         */
+        function shouldAddReturnTypeMetadata(node) {
+            return node.kind === 151 /* MethodDeclaration */;
+        }
+        /**
+         * Determines whether to emit the "design:paramtypes" metadata based on the node's kind.
+         * The caller should have already tested whether the node has decorators and whether the
+         * emitDecoratorMetadata compiler option is set.
+         *
+         * @param node The node to test.
+         */
+        function shouldAddParamTypesMetadata(node) {
+            switch (node.kind) {
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                    return ts.getFirstConstructorWithBody(node) !== undefined;
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return true;
+            }
+            return false;
+        }
+        /**
+         * Serializes the type of a node for use with decorator type metadata.
+         *
+         * @param node The node that should have its type serialized.
+         */
+        function serializeTypeOfNode(node) {
+            switch (node.kind) {
+                case 149 /* PropertyDeclaration */:
+                case 146 /* Parameter */:
+                case 153 /* GetAccessor */:
+                    return serializeTypeNode(node.type);
+                case 154 /* SetAccessor */:
+                    return serializeTypeNode(ts.getSetAccessorTypeAnnotationNode(node));
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                case 151 /* MethodDeclaration */:
+                    return ts.createIdentifier("Function");
+                default:
+                    return ts.createVoidZero();
+            }
+        }
+        /**
+         * Serializes the types of the parameters of a node for use with decorator type metadata.
+         *
+         * @param node The node that should have its parameter types serialized.
+         */
+        function serializeParameterTypesOfNode(node, container) {
+            var valueDeclaration = ts.isClassLike(node)
+                ? ts.getFirstConstructorWithBody(node)
+                : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)
+                    ? node
+                    : undefined;
+            var expressions = [];
+            if (valueDeclaration) {
+                var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
+                var numParameters = parameters.length;
+                for (var i = 0; i < numParameters; i++) {
+                    var parameter = parameters[i];
+                    if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
+                        continue;
+                    }
+                    if (parameter.dotDotDotToken) {
+                        expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type)));
+                    }
+                    else {
+                        expressions.push(serializeTypeOfNode(parameter));
+                    }
+                }
+            }
+            return ts.createArrayLiteral(expressions);
+        }
+        function getParametersOfDecoratedDeclaration(node, container) {
+            if (container && node.kind === 153 /* GetAccessor */) {
+                var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor;
+                if (setAccessor) {
+                    return setAccessor.parameters;
+                }
+            }
+            return node.parameters;
+        }
+        /**
+         * Serializes the return type of a node for use with decorator type metadata.
+         *
+         * @param node The node that should have its return type serialized.
+         */
+        function serializeReturnTypeOfNode(node) {
+            if (ts.isFunctionLike(node) && node.type) {
+                return serializeTypeNode(node.type);
+            }
+            else if (ts.isAsyncFunction(node)) {
+                return ts.createIdentifier("Promise");
+            }
+            return ts.createVoidZero();
+        }
+        /**
+         * Serializes a type node for use with decorator type metadata.
+         *
+         * Types are serialized in the following fashion:
+         * - Void types point to "undefined" (e.g. "void 0")
+         * - Function and Constructor types point to the global "Function" constructor.
+         * - Interface types with a call or construct signature types point to the global
+         *   "Function" constructor.
+         * - Array and Tuple types point to the global "Array" constructor.
+         * - Type predicates and booleans point to the global "Boolean" constructor.
+         * - String literal types and strings point to the global "String" constructor.
+         * - Enum and number types point to the global "Number" constructor.
+         * - Symbol types point to the global "Symbol" constructor.
+         * - Type references to classes (or class-like variables) point to the constructor for the class.
+         * - Anything else points to the global "Object" constructor.
+         *
+         * @param node The type node to serialize.
+         */
+        function serializeTypeNode(node) {
+            if (node === undefined) {
+                return ts.createIdentifier("Object");
+            }
+            switch (node.kind) {
+                case 105 /* VoidKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 95 /* NullKeyword */:
+                case 130 /* NeverKeyword */:
+                    return ts.createVoidZero();
+                case 168 /* ParenthesizedType */:
+                    return serializeTypeNode(node.type);
+                case 160 /* FunctionType */:
+                case 161 /* ConstructorType */:
+                    return ts.createIdentifier("Function");
+                case 164 /* ArrayType */:
+                case 165 /* TupleType */:
+                    return ts.createIdentifier("Array");
+                case 158 /* TypePredicate */:
+                case 122 /* BooleanKeyword */:
+                    return ts.createIdentifier("Boolean");
+                case 136 /* StringKeyword */:
+                    return ts.createIdentifier("String");
+                case 134 /* ObjectKeyword */:
+                    return ts.createIdentifier("Object");
+                case 173 /* LiteralType */:
+                    switch (node.literal.kind) {
+                        case 9 /* StringLiteral */:
+                            return ts.createIdentifier("String");
+                        case 8 /* NumericLiteral */:
+                            return ts.createIdentifier("Number");
+                        case 101 /* TrueKeyword */:
+                        case 86 /* FalseKeyword */:
+                            return ts.createIdentifier("Boolean");
+                        default:
+                            ts.Debug.failBadSyntaxKind(node.literal);
+                            break;
+                    }
+                    break;
+                case 133 /* NumberKeyword */:
+                    return ts.createIdentifier("Number");
+                case 137 /* SymbolKeyword */:
+                    return languageVersion < 2 /* ES2015 */
+                        ? getGlobalSymbolNameWithFallback()
+                        : ts.createIdentifier("Symbol");
+                case 159 /* TypeReference */:
+                    return serializeTypeReferenceNode(node);
+                case 167 /* IntersectionType */:
+                case 166 /* UnionType */:
+                    return serializeUnionOrIntersectionType(node);
+                case 162 /* TypeQuery */:
+                case 170 /* TypeOperator */:
+                case 171 /* IndexedAccessType */:
+                case 172 /* MappedType */:
+                case 163 /* TypeLiteral */:
+                case 119 /* AnyKeyword */:
+                case 169 /* ThisType */:
+                    break;
+                default:
+                    ts.Debug.failBadSyntaxKind(node);
+                    break;
+            }
+            return ts.createIdentifier("Object");
+        }
+        function serializeUnionOrIntersectionType(node) {
+            // Note when updating logic here also update getEntityNameForDecoratorMetadata
+            // so that aliases can be marked as referenced
+            var serializedUnion;
+            for (var _i = 0, _a = node.types; _i < _a.length; _i++) {
+                var typeNode = _a[_i];
+                while (typeNode.kind === 168 /* ParenthesizedType */) {
+                    typeNode = typeNode.type; // Skip parens if need be
+                }
+                if (typeNode.kind === 130 /* NeverKeyword */) {
+                    continue; // Always elide `never` from the union/intersection if possible
+                }
+                if (!strictNullChecks && (typeNode.kind === 95 /* NullKeyword */ || typeNode.kind === 139 /* UndefinedKeyword */)) {
+                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
+                }
+                var serializedIndividual = serializeTypeNode(typeNode);
+                if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
+                    // One of the individual is global object, return immediately
+                    return serializedIndividual;
+                }
+                else if (serializedUnion) {
+                    // Different types
+                    if (!ts.isIdentifier(serializedUnion) ||
+                        !ts.isIdentifier(serializedIndividual) ||
+                        serializedUnion.escapedText !== serializedIndividual.escapedText) {
+                        return ts.createIdentifier("Object");
+                    }
+                }
+                else {
+                    // Initialize the union type
+                    serializedUnion = serializedIndividual;
+                }
+            }
+            // If we were able to find common type, use it
+            return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never
+        }
+        /**
+         * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with
+         * decorator type metadata.
+         *
+         * @param node The type reference node.
+         */
+        function serializeTypeReferenceNode(node) {
+            switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) {
+                case ts.TypeReferenceSerializationKind.Unknown:
+                    var serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true);
+                    var temp = ts.createTempVariable(hoistVariableDeclaration);
+                    return ts.createLogicalOr(ts.createLogicalAnd(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp), ts.createIdentifier("Object"));
+                case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
+                    return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false);
+                case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType:
+                    return ts.createVoidZero();
+                case ts.TypeReferenceSerializationKind.BooleanType:
+                    return ts.createIdentifier("Boolean");
+                case ts.TypeReferenceSerializationKind.NumberLikeType:
+                    return ts.createIdentifier("Number");
+                case ts.TypeReferenceSerializationKind.StringLikeType:
+                    return ts.createIdentifier("String");
+                case ts.TypeReferenceSerializationKind.ArrayLikeType:
+                    return ts.createIdentifier("Array");
+                case ts.TypeReferenceSerializationKind.ESSymbolType:
+                    return languageVersion < 2 /* ES2015 */
+                        ? getGlobalSymbolNameWithFallback()
+                        : ts.createIdentifier("Symbol");
+                case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
+                    return ts.createIdentifier("Function");
+                case ts.TypeReferenceSerializationKind.Promise:
+                    return ts.createIdentifier("Promise");
+                case ts.TypeReferenceSerializationKind.ObjectType:
+                default:
+                    return ts.createIdentifier("Object");
+            }
+        }
+        /**
+         * Serializes an entity name as an expression for decorator type metadata.
+         *
+         * @param node The entity name to serialize.
+         * @param useFallback A value indicating whether to use logical operators to test for the
+         *                    entity name at runtime.
+         */
+        function serializeEntityNameAsExpression(node, useFallback) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    // Create a clone of the name with a new parent, and treat it as if it were
+                    // a source tree node for the purposes of the checker.
+                    var name = ts.getMutableClone(node);
+                    name.flags &= ~8 /* Synthesized */;
+                    name.original = undefined;
+                    name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
+                    if (useFallback) {
+                        return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
+                    }
+                    return name;
+                case 143 /* QualifiedName */:
+                    return serializeQualifiedNameAsExpression(node, useFallback);
+            }
+        }
+        /**
+         * Serializes an qualified name as an expression for decorator type metadata.
+         *
+         * @param node The qualified name to serialize.
+         * @param useFallback A value indicating whether to use logical operators to test for the
+         *                    qualified name at runtime.
+         */
+        function serializeQualifiedNameAsExpression(node, useFallback) {
+            var left;
+            if (node.left.kind === 71 /* Identifier */) {
+                left = serializeEntityNameAsExpression(node.left, useFallback);
+            }
+            else if (useFallback) {
+                var temp = ts.createTempVariable(hoistVariableDeclaration);
+                left = ts.createLogicalAnd(ts.createAssignment(temp, serializeEntityNameAsExpression(node.left, /*useFallback*/ true)), temp);
+            }
+            else {
+                left = serializeEntityNameAsExpression(node.left, /*useFallback*/ false);
+            }
+            return ts.createPropertyAccess(left, node.right);
+        }
+        /**
+         * Gets an expression that points to the global "Symbol" constructor at runtime if it is
+         * available.
+         */
+        function getGlobalSymbolNameWithFallback() {
+            return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object"));
+        }
+        /**
+         * Gets an expression that represents a property name. For a computed property, a
+         * name is generated for the node.
+         *
+         * @param member The member whose name should be converted into an expression.
+         */
+        function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
+            var name = member.name;
+            if (ts.isComputedPropertyName(name)) {
+                return generateNameForComputedPropertyName
+                    ? ts.getGeneratedNameForNode(name)
+                    : name.expression;
+            }
+            else if (ts.isIdentifier(name)) {
+                return ts.createLiteral(ts.idText(name));
+            }
+            else {
+                return ts.getSynthesizedClone(name);
+            }
+        }
+        /**
+         * Visits the property name of a class element, for use when emitting property
+         * initializers. For a computed property on a node with decorators, a temporary
+         * value is stored for later use.
+         *
+         * @param member The member whose name should be visited.
+         */
+        function visitPropertyNameOfClassElement(member) {
+            var name = member.name;
+            if (ts.isComputedPropertyName(name)) {
+                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
+                if (member.decorators) {
+                    var generatedName = ts.getGeneratedNameForNode(name);
+                    hoistVariableDeclaration(generatedName);
+                    expression = ts.createAssignment(generatedName, expression);
+                }
+                return ts.updateComputedPropertyName(name, expression);
+            }
+            else {
+                return name;
+            }
+        }
+        /**
+         * Transforms a HeritageClause with TypeScript syntax.
+         *
+         * This function will only be called when one of the following conditions are met:
+         * - The node is a non-`extends` heritage clause that should be elided.
+         * - The node is an `extends` heritage clause that should be visited, but only allow a single type.
+         *
+         * @param node The HeritageClause to transform.
+         */
+        function visitHeritageClause(node) {
+            if (node.token === 85 /* ExtendsKeyword */) {
+                var types = ts.visitNodes(node.types, visitor, ts.isExpressionWithTypeArguments, 0, 1);
+                return ts.setTextRange(ts.createHeritageClause(85 /* ExtendsKeyword */, types), node);
+            }
+            return undefined;
+        }
+        /**
+         * Transforms an ExpressionWithTypeArguments with TypeScript syntax.
+         *
+         * This function will only be called when one of the following conditions are met:
+         * - The node contains type arguments that should be elided.
+         *
+         * @param node The ExpressionWithTypeArguments to transform.
+         */
+        function visitExpressionWithTypeArguments(node) {
+            return ts.updateExpressionWithTypeArguments(node, 
+            /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
+        }
+        /**
+         * Determines whether to emit a function-like declaration. We should not emit the
+         * declaration if it does not have a body.
+         *
+         * @param node The declaration node.
+         */
+        function shouldEmitFunctionLikeDeclaration(node) {
+            return !ts.nodeIsMissing(node.body);
+        }
+        function visitConstructor(node) {
+            if (!shouldEmitFunctionLikeDeclaration(node)) {
+                return undefined;
+            }
+            return ts.updateConstructor(node, ts.visitNodes(node.decorators, visitor, ts.isDecorator), ts.visitNodes(node.modifiers, visitor, ts.isModifier), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context));
+        }
+        /**
+         * Visits a method declaration of a class.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is an overload
+         * - The node is marked as abstract, public, private, protected, or readonly
+         * - The node has both a decorator and a computed property name
+         *
+         * @param node The method node.
+         */
+        function visitMethodDeclaration(node) {
+            if (!shouldEmitFunctionLikeDeclaration(node)) {
+                return undefined;
+            }
+            var updated = ts.updateMethod(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), 
+            /*questionToken*/ undefined, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context));
+            if (updated !== node) {
+                // While we emit the source map for the node after skipping decorators and modifiers,
+                // we need to emit the comments for the original range.
+                ts.setCommentRange(updated, node);
+                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
+            }
+            return updated;
+        }
+        /**
+         * Determines whether to emit an accessor declaration. We should not emit the
+         * declaration if it does not have a body and is abstract.
+         *
+         * @param node The declaration node.
+         */
+        function shouldEmitAccessorDeclaration(node) {
+            return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */));
+        }
+        /**
+         * Visits a get accessor declaration of a class.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked as abstract, public, private, or protected
+         * - The node has both a decorator and a computed property name
+         *
+         * @param node The get accessor node.
+         */
+        function visitGetAccessor(node) {
+            if (!shouldEmitAccessorDeclaration(node)) {
+                return undefined;
+            }
+            var updated = ts.updateGetAccessor(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
+            if (updated !== node) {
+                // While we emit the source map for the node after skipping decorators and modifiers,
+                // we need to emit the comments for the original range.
+                ts.setCommentRange(updated, node);
+                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
+            }
+            return updated;
+        }
+        /**
+         * Visits a set accessor declaration of a class.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked as abstract, public, private, or protected
+         * - The node has both a decorator and a computed property name
+         *
+         * @param node The set accessor node.
+         */
+        function visitSetAccessor(node) {
+            if (!shouldEmitAccessorDeclaration(node)) {
+                return undefined;
+            }
+            var updated = ts.updateSetAccessor(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
+            if (updated !== node) {
+                // While we emit the source map for the node after skipping decorators and modifiers,
+                // we need to emit the comments for the original range.
+                ts.setCommentRange(updated, node);
+                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
+            }
+            return updated;
+        }
+        /**
+         * Visits a function declaration.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is an overload
+         * - The node is exported from a TypeScript namespace
+         * - The node has decorators
+         *
+         * @param node The function node.
+         */
+        function visitFunctionDeclaration(node) {
+            if (!shouldEmitFunctionLikeDeclaration(node)) {
+                return ts.createNotEmittedStatement(node);
+            }
+            var updated = ts.updateFunctionDeclaration(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
+            if (isExportOfNamespace(node)) {
+                var statements = [updated];
+                addExportMemberAssignment(statements, node);
+                return statements;
+            }
+            return updated;
+        }
+        /**
+         * Visits a function expression node.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node has type annotations
+         *
+         * @param node The function expression node.
+         */
+        function visitFunctionExpression(node) {
+            if (!shouldEmitFunctionLikeDeclaration(node)) {
+                return ts.createOmittedExpression();
+            }
+            var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
+            return updated;
+        }
+        /**
+         * @remarks
+         * This function will be called when one of the following conditions are met:
+         * - The node has type annotations
+         */
+        function visitArrowFunction(node) {
+            var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context));
+            return updated;
+        }
+        /**
+         * Visits a parameter declaration node.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node has an accessibility modifier.
+         * - The node has a questionToken.
+         * - The node's kind is ThisKeyword.
+         *
+         * @param node The parameter declaration node.
+         */
+        function visitParameter(node) {
+            if (ts.parameterIsThisKeyword(node)) {
+                return undefined;
+            }
+            var parameter = ts.createParameter(
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), 
+            /*questionToken*/ undefined, 
+            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
+            // While we emit the source map for the node after skipping decorators and modifiers,
+            // we need to emit the comments for the original range.
+            ts.setOriginalNode(parameter, node);
+            ts.setTextRange(parameter, ts.moveRangePastModifiers(node));
+            ts.setCommentRange(parameter, node);
+            ts.setSourceMapRange(parameter, ts.moveRangePastModifiers(node));
+            ts.setEmitFlags(parameter.name, 32 /* NoTrailingSourceMap */);
+            return parameter;
+        }
+        /**
+         * Visits a variable statement in a namespace.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is exported from a TypeScript namespace.
+         */
+        function visitVariableStatement(node) {
+            if (isExportOfNamespace(node)) {
+                var variables = ts.getInitializedVariables(node.declarationList);
+                if (variables.length === 0) {
+                    // elide statement if there are no initialized variables.
+                    return undefined;
+                }
+                return ts.setTextRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
+            }
+            else {
+                return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function transformInitializedVariable(node) {
+            var name = node.name;
+            if (ts.isBindingPattern(name)) {
+                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, 
+                /*needsValue*/ false, createNamespaceExportExpression);
+            }
+            else {
+                return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), 
+                /*location*/ node);
+            }
+        }
+        function visitVariableDeclaration(node) {
+            return ts.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), 
+            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
+        }
+        /**
+         * Visits a parenthesized expression that contains either a type assertion or an `as`
+         * expression.
+         *
+         * @param node The parenthesized expression node.
+         */
+        function visitParenthesizedExpression(node) {
+            var innerExpression = ts.skipOuterExpressions(node.expression, ~2 /* Assertions */);
+            if (ts.isAssertionExpression(innerExpression)) {
+                // Make sure we consider all nested cast expressions, e.g.:
+                // (<any><number><any>-A).x;
+                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+                // We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
+                // is really not desirable. We would like to emit the subexpression as-is. Omitting
+                // the parentheses, however, could cause change in the semantics of the generated
+                // code if the casted expression has a lower precedence than the rest of the
+                // expression.
+                //
+                // To preserve comments, we return a "PartiallyEmittedExpression" here which will
+                // preserve the position information of the original expression.
+                //
+                // Due to the auto-parenthesization rules used by the visitor and factory functions
+                // we can safely elide the parentheses here, as a new synthetic
+                // ParenthesizedExpression will be inserted if we remove parentheses too
+                // aggressively.
+                return ts.createPartiallyEmittedExpression(expression, node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitAssertionExpression(node) {
+            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+            return ts.createPartiallyEmittedExpression(expression, node);
+        }
+        function visitNonNullExpression(node) {
+            var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression);
+            return ts.createPartiallyEmittedExpression(expression, node);
+        }
+        function visitCallExpression(node) {
+            return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
+            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
+        }
+        function visitNewExpression(node) {
+            return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
+            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
+        }
+        /**
+         * Determines whether to emit an enum declaration.
+         *
+         * @param node The enum declaration node.
+         */
+        function shouldEmitEnumDeclaration(node) {
+            return !ts.isConst(node)
+                || compilerOptions.preserveConstEnums
+                || compilerOptions.isolatedModules;
+        }
+        /**
+         * Visits an enum declaration.
+         *
+         * This function will be called any time a TypeScript enum is encountered.
+         *
+         * @param node The enum declaration node.
+         */
+        function visitEnumDeclaration(node) {
+            if (!shouldEmitEnumDeclaration(node)) {
+                return undefined;
+            }
+            var statements = [];
+            // We request to be advised when the printer is about to print this node. This allows
+            // us to set up the correct state for later substitutions.
+            var emitFlags = 2 /* AdviseOnEmitNode */;
+            // If needed, we should emit a variable declaration for the enum. If we emit
+            // a leading variable declaration, we should not emit leading comments for the
+            // enum body.
+            if (addVarForEnumOrModuleDeclaration(statements, node)) {
+                // We should still emit the comments if we are emitting a system module.
+                if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) {
+                    emitFlags |= 512 /* NoLeadingComments */;
+                }
+            }
+            // `parameterName` is the declaration name used inside of the enum.
+            var parameterName = getNamespaceParameterName(node);
+            // `containerName` is the expression used inside of the enum for assignments.
+            var containerName = getNamespaceContainerName(node);
+            // `exportName` is the expression used within this node's container for any exported references.
+            var exportName = ts.hasModifier(node, 1 /* Export */)
+                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
+                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+            //  x || (x = {})
+            //  exports.x || (exports.x = {})
+            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
+            if (hasNamespaceQualifiedExportName(node)) {
+                // `localName` is the expression used within this node's containing scope for any local references.
+                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+                //  x = (exports.x || (exports.x = {}))
+                moduleArg = ts.createAssignment(localName, moduleArg);
+            }
+            //  (function (x) {
+            //      x[x["y"] = 0] = "y";
+            //      ...
+            //  })(x || (x = {}));
+            var enumStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
+            /*type*/ undefined, transformEnumBody(node, containerName)), 
+            /*typeArguments*/ undefined, [moduleArg]));
+            ts.setOriginalNode(enumStatement, node);
+            ts.setTextRange(enumStatement, node);
+            ts.setEmitFlags(enumStatement, emitFlags);
+            statements.push(enumStatement);
+            // Add a DeclarationMarker for the enum to preserve trailing comments and mark
+            // the end of the declaration.
+            statements.push(ts.createEndOfDeclarationMarker(node));
+            return statements;
+        }
+        /**
+         * Transforms the body of an enum declaration.
+         *
+         * @param node The enum declaration node.
+         */
+        function transformEnumBody(node, localName) {
+            var savedCurrentNamespaceLocalName = currentNamespaceContainerName;
+            currentNamespaceContainerName = localName;
+            var statements = [];
+            startLexicalEnvironment();
+            ts.addRange(statements, ts.map(node.members, transformEnumMember));
+            ts.addRange(statements, endLexicalEnvironment());
+            currentNamespaceContainerName = savedCurrentNamespaceLocalName;
+            return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), 
+            /*multiLine*/ true);
+        }
+        /**
+         * Transforms an enum member into a statement.
+         *
+         * @param member The enum member node.
+         */
+        function transformEnumMember(member) {
+            // enums don't support computed properties
+            // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
+            // old emitter always generate 'expression' part of the name as-is.
+            var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
+            var valueExpression = transformEnumMemberDeclarationValue(member);
+            var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression);
+            var outerAssignment = valueExpression.kind === 9 /* StringLiteral */ ?
+                innerAssignment :
+                ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name);
+            return ts.setTextRange(ts.createStatement(ts.setTextRange(outerAssignment, member)), member);
+        }
+        /**
+         * Transforms the value of an enum member.
+         *
+         * @param member The enum member node.
+         */
+        function transformEnumMemberDeclarationValue(member) {
+            var value = resolver.getConstantValue(member);
+            if (value !== undefined) {
+                return ts.createLiteral(value);
+            }
+            else {
+                enableSubstitutionForNonQualifiedEnumMembers();
+                if (member.initializer) {
+                    return ts.visitNode(member.initializer, visitor, ts.isExpression);
+                }
+                else {
+                    return ts.createVoidZero();
+                }
+            }
+        }
+        /**
+         * Determines whether to elide a module declaration.
+         *
+         * @param node The module declaration node.
+         */
+        function shouldEmitModuleDeclaration(node) {
+            return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
+        }
+        /**
+         * Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
+         * or `exports.x`).
+         */
+        function hasNamespaceQualifiedExportName(node) {
+            return isExportOfNamespace(node)
+                || (isExternalModuleExport(node)
+                    && moduleKind !== ts.ModuleKind.ES2015
+                    && moduleKind !== ts.ModuleKind.ESNext
+                    && moduleKind !== ts.ModuleKind.System);
+        }
+        /**
+         * Records that a declaration was emitted in the current scope, if it was the first
+         * declaration for the provided symbol.
+         */
+        function recordEmittedDeclarationInScope(node) {
+            if (!currentScopeFirstDeclarationsOfName) {
+                currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap();
+            }
+            var name = declaredNameInScope(node);
+            if (!currentScopeFirstDeclarationsOfName.has(name)) {
+                currentScopeFirstDeclarationsOfName.set(name, node);
+            }
+        }
+        /**
+         * Determines whether a declaration is the first declaration with
+         * the same name emitted in the current scope.
+         */
+        function isFirstEmittedDeclarationInScope(node) {
+            if (currentScopeFirstDeclarationsOfName) {
+                var name = declaredNameInScope(node);
+                return currentScopeFirstDeclarationsOfName.get(name) === node;
+            }
+            return true;
+        }
+        function declaredNameInScope(node) {
+            ts.Debug.assertNode(node.name, ts.isIdentifier);
+            return node.name.escapedText;
+        }
+        /**
+         * Adds a leading VariableStatement for a enum or module declaration.
+         */
+        function addVarForEnumOrModuleDeclaration(statements, node) {
+            // Emit a variable statement for the module. We emit top-level enums as a `var`
+            // declaration to avoid static errors in global scripts scripts due to redeclaration.
+            // enums in any other scope are emitted as a `let` declaration.
+            var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))
+            ], currentScope.kind === 265 /* SourceFile */ ? 0 /* None */ : 1 /* Let */));
+            ts.setOriginalNode(statement, node);
+            recordEmittedDeclarationInScope(node);
+            if (isFirstEmittedDeclarationInScope(node)) {
+                // Adjust the source map emit to match the old emitter.
+                if (node.kind === 232 /* EnumDeclaration */) {
+                    ts.setSourceMapRange(statement.declarationList, node);
+                }
+                else {
+                    ts.setSourceMapRange(statement, node);
+                }
+                // Trailing comments for module declaration should be emitted after the function closure
+                // instead of the variable statement:
+                //
+                //     /** Module comment*/
+                //     module m1 {
+                //         function foo4Export() {
+                //         }
+                //     } // trailing comment module
+                //
+                // Should emit:
+                //
+                //     /** Module comment*/
+                //     var m1;
+                //     (function (m1) {
+                //         function foo4Export() {
+                //         }
+                //     })(m1 || (m1 = {})); // trailing comment module
+                //
+                ts.setCommentRange(statement, node);
+                ts.setEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */);
+                statements.push(statement);
+                return true;
+            }
+            else {
+                // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
+                // declaration we do not emit a leading variable declaration. To preserve the
+                // begin/end semantics of the declararation and to properly handle exports
+                // we wrap the leading variable declaration in a `MergeDeclarationMarker`.
+                var mergeMarker = ts.createMergeDeclarationMarker(statement);
+                ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */);
+                statements.push(mergeMarker);
+                return false;
+            }
+        }
+        /**
+         * Visits a module declaration node.
+         *
+         * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered.
+         *
+         * @param node The module declaration node.
+         */
+        function visitModuleDeclaration(node) {
+            if (!shouldEmitModuleDeclaration(node)) {
+                return ts.createNotEmittedStatement(node);
+            }
+            ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name.");
+            enableSubstitutionForNamespaceExports();
+            var statements = [];
+            // We request to be advised when the printer is about to print this node. This allows
+            // us to set up the correct state for later substitutions.
+            var emitFlags = 2 /* AdviseOnEmitNode */;
+            // If needed, we should emit a variable declaration for the module. If we emit
+            // a leading variable declaration, we should not emit leading comments for the
+            // module body.
+            if (addVarForEnumOrModuleDeclaration(statements, node)) {
+                // We should still emit the comments if we are emitting a system module.
+                if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) {
+                    emitFlags |= 512 /* NoLeadingComments */;
+                }
+            }
+            // `parameterName` is the declaration name used inside of the namespace.
+            var parameterName = getNamespaceParameterName(node);
+            // `containerName` is the expression used inside of the namespace for exports.
+            var containerName = getNamespaceContainerName(node);
+            // `exportName` is the expression used within this node's container for any exported references.
+            var exportName = ts.hasModifier(node, 1 /* Export */)
+                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
+                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+            //  x || (x = {})
+            //  exports.x || (exports.x = {})
+            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
+            if (hasNamespaceQualifiedExportName(node)) {
+                // `localName` is the expression used within this node's containing scope for any local references.
+                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
+                //  x = (exports.x || (exports.x = {}))
+                moduleArg = ts.createAssignment(localName, moduleArg);
+            }
+            //  (function (x_1) {
+            //      x_1.y = ...;
+            //  })(x || (x = {}));
+            var moduleStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
+            /*type*/ undefined, transformModuleBody(node, containerName)), 
+            /*typeArguments*/ undefined, [moduleArg]));
+            ts.setOriginalNode(moduleStatement, node);
+            ts.setTextRange(moduleStatement, node);
+            ts.setEmitFlags(moduleStatement, emitFlags);
+            statements.push(moduleStatement);
+            // Add a DeclarationMarker for the namespace to preserve trailing comments and mark
+            // the end of the declaration.
+            statements.push(ts.createEndOfDeclarationMarker(node));
+            return statements;
+        }
+        /**
+         * Transforms the body of a module declaration.
+         *
+         * @param node The module declaration node.
+         */
+        function transformModuleBody(node, namespaceLocalName) {
+            var savedCurrentNamespaceContainerName = currentNamespaceContainerName;
+            var savedCurrentNamespace = currentNamespace;
+            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
+            currentNamespaceContainerName = namespaceLocalName;
+            currentNamespace = node;
+            currentScopeFirstDeclarationsOfName = undefined;
+            var statements = [];
+            startLexicalEnvironment();
+            var statementsLocation;
+            var blockLocation;
+            var body = node.body;
+            if (body.kind === 234 /* ModuleBlock */) {
+                saveStateAndInvoke(body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); });
+                statementsLocation = body.statements;
+                blockLocation = body;
+            }
+            else {
+                var result = visitModuleDeclaration(body);
+                if (result) {
+                    if (ts.isArray(result)) {
+                        ts.addRange(statements, result);
+                    }
+                    else {
+                        statements.push(result);
+                    }
+                }
+                var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
+                statementsLocation = ts.moveRangePos(moduleBlock.statements, -1);
+            }
+            ts.addRange(statements, endLexicalEnvironment());
+            currentNamespaceContainerName = savedCurrentNamespaceContainerName;
+            currentNamespace = savedCurrentNamespace;
+            currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
+            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
+            /*location*/ statementsLocation), 
+            /*multiLine*/ true);
+            ts.setTextRange(block, blockLocation);
+            // namespace hello.hi.world {
+            //      function foo() {}
+            //
+            //      // TODO, blah
+            // }
+            //
+            // should be emitted as
+            //
+            // var hello;
+            // (function (hello) {
+            //     var hi;
+            //     (function (hi) {
+            //         var world;
+            //         (function (world) {
+            //             function foo() { }
+            //             // TODO, blah
+            //         })(world = hi.world || (hi.world = {}));
+            //     })(hi = hello.hi || (hello.hi = {}));
+            // })(hello || (hello = {}));
+            // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
+            if (body.kind !== 234 /* ModuleBlock */) {
+                ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */);
+            }
+            return block;
+        }
+        function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
+            if (moduleDeclaration.body.kind === 233 /* ModuleDeclaration */) {
+                var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
+                return recursiveInnerModule || moduleDeclaration.body;
+            }
+        }
+        /**
+         * Visits an import declaration, eliding it if it is not referenced.
+         *
+         * @param node The import declaration node.
+         */
+        function visitImportDeclaration(node) {
+            if (!node.importClause) {
+                // Do not elide a side-effect only import declaration.
+                //  import "foo";
+                return node;
+            }
+            // Elide the declaration if the import clause was elided.
+            var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause);
+            return importClause
+                ? ts.updateImportDeclaration(node, 
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, importClause, node.moduleSpecifier)
+                : undefined;
+        }
+        /**
+         * Visits an import clause, eliding it if it is not referenced.
+         *
+         * @param node The import clause node.
+         */
+        function visitImportClause(node) {
+            // Elide the import clause if we elide both its name and its named bindings.
+            var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
+            var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings);
+            return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings) : undefined;
+        }
+        /**
+         * Visits named import bindings, eliding it if it is not referenced.
+         *
+         * @param node The named import bindings node.
+         */
+        function visitNamedImportBindings(node) {
+            if (node.kind === 240 /* NamespaceImport */) {
+                // Elide a namespace import if it is not referenced.
+                return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
+            }
+            else {
+                // Elide named imports if all of its import specifiers are elided.
+                var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier);
+                return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined;
+            }
+        }
+        /**
+         * Visits an import specifier, eliding it if it is not referenced.
+         *
+         * @param node The import specifier node.
+         */
+        function visitImportSpecifier(node) {
+            // Elide an import specifier if it is not referenced.
+            return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
+        }
+        /**
+         * Visits an export assignment, eliding it if it does not contain a clause that resolves
+         * to a value.
+         *
+         * @param node The export assignment node.
+         */
+        function visitExportAssignment(node) {
+            // Elide the export assignment if it does not reference a value.
+            return resolver.isValueAliasDeclaration(node)
+                ? ts.visitEachChild(node, visitor, context)
+                : undefined;
+        }
+        /**
+         * Visits an export declaration, eliding it if it does not contain a clause that resolves
+         * to a value.
+         *
+         * @param node The export declaration node.
+         */
+        function visitExportDeclaration(node) {
+            if (!node.exportClause) {
+                // Elide a star export if the module it references does not export a value.
+                return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
+            }
+            if (!resolver.isValueAliasDeclaration(node)) {
+                // Elide the export declaration if it does not export a value.
+                return undefined;
+            }
+            // Elide the export declaration if all of its named exports are elided.
+            var exportClause = ts.visitNode(node.exportClause, visitNamedExports, ts.isNamedExports);
+            return exportClause
+                ? ts.updateExportDeclaration(node, 
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, exportClause, node.moduleSpecifier)
+                : undefined;
+        }
+        /**
+         * Visits named exports, eliding it if it does not contain an export specifier that
+         * resolves to a value.
+         *
+         * @param node The named exports node.
+         */
+        function visitNamedExports(node) {
+            // Elide the named exports if all of its export specifiers were elided.
+            var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier);
+            return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined;
+        }
+        /**
+         * Visits an export specifier, eliding it if it does not resolve to a value.
+         *
+         * @param node The export specifier node.
+         */
+        function visitExportSpecifier(node) {
+            // Elide an export specifier if it does not reference a value.
+            return resolver.isValueAliasDeclaration(node) ? node : undefined;
+        }
+        /**
+         * Determines whether to emit an import equals declaration.
+         *
+         * @param node The import equals declaration node.
+         */
+        function shouldEmitImportEqualsDeclaration(node) {
+            // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
+            // - current file is not external module
+            // - import declaration is top level and target is value imported by entity name
+            return resolver.isReferencedAliasDeclaration(node)
+                || (!ts.isExternalModule(currentSourceFile)
+                    && resolver.isTopLevelValueImportEqualsWithEntityName(node));
+        }
+        /**
+         * Visits an import equals declaration.
+         *
+         * @param node The import equals declaration node.
+         */
+        function visitImportEqualsDeclaration(node) {
+            if (ts.isExternalModuleImportEqualsDeclaration(node)) {
+                // Elide external module `import=` if it is not referenced.
+                return resolver.isReferencedAliasDeclaration(node)
+                    ? ts.visitEachChild(node, visitor, context)
+                    : undefined;
+            }
+            if (!shouldEmitImportEqualsDeclaration(node)) {
+                return undefined;
+            }
+            var moduleReference = ts.createExpressionFromEntityName(node.moduleReference);
+            ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
+            if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
+                //  export var ${name} = ${moduleReference};
+                //  var ${name} = ${moduleReference};
+                return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
+                    ts.setOriginalNode(ts.createVariableDeclaration(node.name, 
+                    /*type*/ undefined, moduleReference), node)
+                ])), node), node);
+            }
+            else {
+                // exports.${name} = ${moduleReference};
+                return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node);
+            }
+        }
+        /**
+         * Gets a value indicating whether the node is exported from a namespace.
+         *
+         * @param node The node to test.
+         */
+        function isExportOfNamespace(node) {
+            return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */);
+        }
+        /**
+         * Gets a value indicating whether the node is exported from an external module.
+         *
+         * @param node The node to test.
+         */
+        function isExternalModuleExport(node) {
+            return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */);
+        }
+        /**
+         * Gets a value indicating whether the node is a named export from an external module.
+         *
+         * @param node The node to test.
+         */
+        function isNamedExternalModuleExport(node) {
+            return isExternalModuleExport(node)
+                && !ts.hasModifier(node, 512 /* Default */);
+        }
+        /**
+         * Gets a value indicating whether the node is the default export of an external module.
+         *
+         * @param node The node to test.
+         */
+        function isDefaultExternalModuleExport(node) {
+            return isExternalModuleExport(node)
+                && ts.hasModifier(node, 512 /* Default */);
+        }
+        /**
+         * Creates a statement for the provided expression. This is used in calls to `map`.
+         */
+        function expressionToStatement(expression) {
+            return ts.createStatement(expression);
+        }
+        function addExportMemberAssignment(statements, node) {
+            var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node));
+            ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end));
+            var statement = ts.createStatement(expression);
+            ts.setSourceMapRange(statement, ts.createRange(-1, node.end));
+            statements.push(statement);
+        }
+        function createNamespaceExport(exportName, exportValue, location) {
+            return ts.setTextRange(ts.createStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location);
+        }
+        function createNamespaceExportExpression(exportName, exportValue, location) {
+            return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
+        }
+        function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
+            return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
+        }
+        /**
+         * Gets the declaration name used inside of a namespace or enum.
+         */
+        function getNamespaceParameterName(node) {
+            var name = ts.getGeneratedNameForNode(node);
+            ts.setSourceMapRange(name, node.name);
+            return name;
+        }
+        /**
+         * Gets the expression used to refer to a namespace or enum within the body
+         * of its declaration.
+         */
+        function getNamespaceContainerName(node) {
+            return ts.getGeneratedNameForNode(node);
+        }
+        /**
+         * Gets a local alias for a class declaration if it is a decorated class with an internal
+         * reference to the static side of the class. This is necessary to avoid issues with
+         * double-binding semantics for the class name.
+         */
+        function getClassAliasIfNeeded(node) {
+            if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) {
+                enableSubstitutionForClassAliases();
+                var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default");
+                classAliases[ts.getOriginalNodeId(node)] = classAlias;
+                hoistVariableDeclaration(classAlias);
+                return classAlias;
+            }
+        }
+        function getClassPrototype(node) {
+            return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype");
+        }
+        function getClassMemberPrefix(node, member) {
+            return ts.hasModifier(member, 32 /* Static */)
+                ? ts.getDeclarationName(node)
+                : getClassPrototype(node);
+        }
+        function enableSubstitutionForNonQualifiedEnumMembers() {
+            if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
+                enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
+                context.enableSubstitution(71 /* Identifier */);
+            }
+        }
+        function enableSubstitutionForClassAliases() {
+            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
+                enabledSubstitutions |= 1 /* ClassAliases */;
+                // We need to enable substitutions for identifiers. This allows us to
+                // substitute class names inside of a class declaration.
+                context.enableSubstitution(71 /* Identifier */);
+                // Keep track of class aliases.
+                classAliases = [];
+            }
+        }
+        function enableSubstitutionForNamespaceExports() {
+            if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
+                enabledSubstitutions |= 2 /* NamespaceExports */;
+                // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to
+                // substitute the names of exported members of a namespace.
+                context.enableSubstitution(71 /* Identifier */);
+                context.enableSubstitution(262 /* ShorthandPropertyAssignment */);
+                // We need to be notified when entering and exiting namespaces.
+                context.enableEmitNotification(233 /* ModuleDeclaration */);
+            }
+        }
+        function isTransformedModuleDeclaration(node) {
+            return ts.getOriginalNode(node).kind === 233 /* ModuleDeclaration */;
+        }
+        function isTransformedEnumDeclaration(node) {
+            return ts.getOriginalNode(node).kind === 232 /* EnumDeclaration */;
+        }
+        /**
+         * Hook for node emit.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emit A callback used to emit the node in the printer.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            var savedApplicableSubstitutions = applicableSubstitutions;
+            var savedCurrentSourceFile = currentSourceFile;
+            if (ts.isSourceFile(node)) {
+                currentSourceFile = node;
+            }
+            if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
+                applicableSubstitutions |= 2 /* NamespaceExports */;
+            }
+            if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
+                applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
+            }
+            previousOnEmitNode(hint, node, emitCallback);
+            applicableSubstitutions = savedApplicableSubstitutions;
+            currentSourceFile = savedCurrentSourceFile;
+        }
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (hint === 1 /* Expression */) {
+                return substituteExpression(node);
+            }
+            else if (ts.isShorthandPropertyAssignment(node)) {
+                return substituteShorthandPropertyAssignment(node);
+            }
+            return node;
+        }
+        function substituteShorthandPropertyAssignment(node) {
+            if (enabledSubstitutions & 2 /* NamespaceExports */) {
+                var name = node.name;
+                var exportedName = trySubstituteNamespaceExportedName(name);
+                if (exportedName) {
+                    // A shorthand property with an assignment initializer is probably part of a
+                    // destructuring assignment
+                    if (node.objectAssignmentInitializer) {
+                        var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer);
+                        return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
+                    }
+                    return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node);
+                }
+            }
+            return node;
+        }
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return substituteExpressionIdentifier(node);
+                case 179 /* PropertyAccessExpression */:
+                    return substitutePropertyAccessExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return substituteElementAccessExpression(node);
+            }
+            return node;
+        }
+        function substituteExpressionIdentifier(node) {
+            return trySubstituteClassAlias(node)
+                || trySubstituteNamespaceExportedName(node)
+                || node;
+        }
+        function trySubstituteClassAlias(node) {
+            if (enabledSubstitutions & 1 /* ClassAliases */) {
+                if (resolver.getNodeCheckFlags(node) & 16777216 /* ConstructorReferenceInClass */) {
+                    // Due to the emit for class decorators, any reference to the class from inside of the class body
+                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
+                    // behavior of class names in ES6.
+                    // Also, when emitting statics for class expressions, we must substitute a class alias for
+                    // constructor references in static property initializers.
+                    var declaration = resolver.getReferencedValueDeclaration(node);
+                    if (declaration) {
+                        var classAlias = classAliases[declaration.id];
+                        if (classAlias) {
+                            var clone_1 = ts.getSynthesizedClone(classAlias);
+                            ts.setSourceMapRange(clone_1, node);
+                            ts.setCommentRange(clone_1, node);
+                            return clone_1;
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        function trySubstituteNamespaceExportedName(node) {
+            // If this is explicitly a local name, do not substitute.
+            if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
+                // If we are nested within a namespace declaration, we may need to qualifiy
+                // an identifier that is exported from a merged namespace.
+                var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
+                if (container && container.kind !== 265 /* SourceFile */) {
+                    var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 233 /* ModuleDeclaration */) ||
+                        (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 232 /* EnumDeclaration */);
+                    if (substitute) {
+                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), 
+                        /*location*/ node);
+                    }
+                }
+            }
+            return undefined;
+        }
+        function substitutePropertyAccessExpression(node) {
+            return substituteConstantValue(node);
+        }
+        function substituteElementAccessExpression(node) {
+            return substituteConstantValue(node);
+        }
+        function substituteConstantValue(node) {
+            var constantValue = tryGetConstEnumValue(node);
+            if (constantValue !== undefined) {
+                // track the constant value on the node for the printer in needsDotDotForPropertyAccess
+                ts.setConstantValue(node, constantValue);
+                var substitute = ts.createLiteral(constantValue);
+                if (!compilerOptions.removeComments) {
+                    var propertyName = ts.isPropertyAccessExpression(node)
+                        ? ts.declarationNameToString(node.name)
+                        : ts.getTextOfNode(node.argumentExpression);
+                    ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " ");
+                }
+                return substitute;
+            }
+            return node;
+        }
+        function tryGetConstEnumValue(node) {
+            if (compilerOptions.isolatedModules) {
+                return undefined;
+            }
+            return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)
+                ? resolver.getConstantValue(node)
+                : undefined;
+        }
+    }
+    ts.transformTypeScript = transformTypeScript;
+    function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) {
+        var argumentsArray = [];
+        argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
+        argumentsArray.push(target);
+        if (memberName) {
+            argumentsArray.push(memberName);
+            if (descriptor) {
+                argumentsArray.push(descriptor);
+            }
+        }
+        context.requestEmitHelper(decorateHelper);
+        return ts.setTextRange(ts.createCall(ts.getHelperName("__decorate"), 
+        /*typeArguments*/ undefined, argumentsArray), location);
+    }
+    var decorateHelper = {
+        name: "typescript:decorate",
+        scoped: false,
+        priority: 2,
+        text: "\n            var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n                var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n                if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n                else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n                return c > 3 && r && Object.defineProperty(target, key, r), r;\n            };"
+    };
+    function createMetadataHelper(context, metadataKey, metadataValue) {
+        context.requestEmitHelper(metadataHelper);
+        return ts.createCall(ts.getHelperName("__metadata"), 
+        /*typeArguments*/ undefined, [
+            ts.createLiteral(metadataKey),
+            metadataValue
+        ]);
+    }
+    var metadataHelper = {
+        name: "typescript:metadata",
+        scoped: false,
+        priority: 3,
+        text: "\n            var __metadata = (this && this.__metadata) || function (k, v) {\n                if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n            };"
+    };
+    function createParamHelper(context, expression, parameterOffset, location) {
+        context.requestEmitHelper(paramHelper);
+        return ts.setTextRange(ts.createCall(ts.getHelperName("__param"), 
+        /*typeArguments*/ undefined, [
+            ts.createLiteral(parameterOffset),
+            expression
+        ]), location);
+    }
+    var paramHelper = {
+        name: "typescript:param",
+        scoped: false,
+        priority: 4,
+        text: "\n            var __param = (this && this.__param) || function (paramIndex, decorator) {\n                return function (target, key) { decorator(target, key, paramIndex); }\n            };"
+    };
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    var ES2017SubstitutionFlags;
+    (function (ES2017SubstitutionFlags) {
+        /** Enables substitutions for async methods with `super` calls. */
+        ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
+    })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {}));
+    function transformES2017(context) {
+        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment;
+        var resolver = context.getEmitResolver();
+        var compilerOptions = context.getCompilerOptions();
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        /**
+         * Keeps track of whether expression substitution has been enabled for specific edge cases.
+         * They are persisted between each SourceFile transformation and should not be reset.
+         */
+        var enabledSubstitutions;
+        /**
+         * This keeps track of containers where `super` is valid, for use with
+         * just-in-time substitution for `super` expressions inside of async methods.
+         */
+        var enclosingSuperContainerFlags = 0;
+        // Save the previous transformation hooks.
+        var previousOnEmitNode = context.onEmitNode;
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        // Set new transformation hooks.
+        context.onEmitNode = onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            var visited = ts.visitEachChild(node, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        }
+        function visitor(node) {
+            if ((node.transformFlags & 16 /* ContainsES2017 */) === 0) {
+                return node;
+            }
+            switch (node.kind) {
+                case 120 /* AsyncKeyword */:
+                    // ES2017 async modifier should be elided for targets < ES2017
+                    return undefined;
+                case 191 /* AwaitExpression */:
+                    return visitAwaitExpression(node);
+                case 151 /* MethodDeclaration */:
+                    return visitMethodDeclaration(node);
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 186 /* FunctionExpression */:
+                    return visitFunctionExpression(node);
+                case 187 /* ArrowFunction */:
+                    return visitArrowFunction(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        /**
+         * Visits an AwaitExpression node.
+         *
+         * This function will be called any time a ES2017 await expression is encountered.
+         *
+         * @param node The node to visit.
+         */
+        function visitAwaitExpression(node) {
+            return ts.setOriginalNode(ts.setTextRange(ts.createYield(
+            /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node);
+        }
+        /**
+         * Visits a MethodDeclaration node.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked as async
+         *
+         * @param node The node to visit.
+         */
+        function visitMethodDeclaration(node) {
+            return ts.updateMethod(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
+            /*questionToken*/ undefined, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
+                ? transformAsyncFunctionBody(node)
+                : ts.visitFunctionBody(node.body, visitor, context));
+        }
+        /**
+         * Visits a FunctionDeclaration node.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked async
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionDeclaration(node) {
+            return ts.updateFunctionDeclaration(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
+                ? transformAsyncFunctionBody(node)
+                : ts.visitFunctionBody(node.body, visitor, context));
+        }
+        /**
+         * Visits a FunctionExpression node.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked async
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionExpression(node) {
+            return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
+                ? transformAsyncFunctionBody(node)
+                : ts.visitFunctionBody(node.body, visitor, context));
+        }
+        /**
+         * Visits an ArrowFunction.
+         *
+         * This function will be called when one of the following conditions are met:
+         * - The node is marked async
+         *
+         * @param node The node to visit.
+         */
+        function visitArrowFunction(node) {
+            return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */
+                ? transformAsyncFunctionBody(node)
+                : ts.visitFunctionBody(node.body, visitor, context));
+        }
+        function transformAsyncFunctionBody(node) {
+            resumeLexicalEnvironment();
+            var original = ts.getOriginalNode(node, ts.isFunctionLike);
+            var nodeType = original.type;
+            var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined;
+            var isArrowFunction = node.kind === 187 /* ArrowFunction */;
+            var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0;
+            // An async function is emit as an outer function that calls an inner
+            // generator function. To preserve lexical bindings, we pass the current
+            // `this` and `arguments` objects to `__awaiter`. The generator function
+            // passed to `__awaiter` is executed inside of the callback to the
+            // promise constructor.
+            if (!isArrowFunction) {
+                var statements = [];
+                var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
+                statements.push(ts.createReturn(createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body, statementOffset))));
+                ts.addRange(statements, endLexicalEnvironment());
+                var block = ts.createBlock(statements, /*multiLine*/ true);
+                ts.setTextRange(block, node.body);
+                // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
+                // This step isn't needed if we eventually transform this to ES5.
+                if (languageVersion >= 2 /* ES2015 */) {
+                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
+                        enableSubstitutionForAsyncMethodsWithSuper();
+                        ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
+                    }
+                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
+                        enableSubstitutionForAsyncMethodsWithSuper();
+                        ts.addEmitHelper(block, ts.asyncSuperHelper);
+                    }
+                }
+                return block;
+            }
+            else {
+                var expression = createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body));
+                var declarations = endLexicalEnvironment();
+                if (ts.some(declarations)) {
+                    var block = ts.convertToFunctionBody(expression);
+                    return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(block.statements, declarations)), block.statements));
+                }
+                return expression;
+            }
+        }
+        function transformFunctionBodyWorker(body, start) {
+            if (ts.isBlock(body)) {
+                return ts.updateBlock(body, ts.visitLexicalEnvironment(body.statements, visitor, context, start));
+            }
+            else {
+                startLexicalEnvironment();
+                var visited = ts.convertToFunctionBody(ts.visitNode(body, visitor, ts.isConciseBody));
+                var declarations = endLexicalEnvironment();
+                return ts.updateBlock(visited, ts.setTextRange(ts.createNodeArray(ts.concatenate(visited.statements, declarations)), visited.statements));
+            }
+        }
+        function getPromiseConstructor(type) {
+            var typeName = type && ts.getEntityNameFromTypeNode(type);
+            if (typeName && ts.isEntityName(typeName)) {
+                var serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
+                if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
+                    || serializationKind === ts.TypeReferenceSerializationKind.Unknown) {
+                    return typeName;
+                }
+            }
+            return undefined;
+        }
+        function enableSubstitutionForAsyncMethodsWithSuper() {
+            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
+                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
+                // We need to enable substitutions for call, property access, and element access
+                // if we need to rewrite super calls.
+                context.enableSubstitution(181 /* CallExpression */);
+                context.enableSubstitution(179 /* PropertyAccessExpression */);
+                context.enableSubstitution(180 /* ElementAccessExpression */);
+                // We need to be notified when entering and exiting declarations that bind super.
+                context.enableEmitNotification(229 /* ClassDeclaration */);
+                context.enableEmitNotification(151 /* MethodDeclaration */);
+                context.enableEmitNotification(153 /* GetAccessor */);
+                context.enableEmitNotification(154 /* SetAccessor */);
+                context.enableEmitNotification(152 /* Constructor */);
+            }
+        }
+        /**
+         * Hook for node emit.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emit A callback used to emit the node in the printer.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            // If we need to support substitutions for `super` in an async method,
+            // we should track it here.
+            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
+                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
+                if (superContainerFlags !== enclosingSuperContainerFlags) {
+                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
+                    enclosingSuperContainerFlags = superContainerFlags;
+                    previousOnEmitNode(hint, node, emitCallback);
+                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
+                    return;
+                }
+            }
+            previousOnEmitNode(hint, node, emitCallback);
+        }
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
+                return substituteExpression(node);
+            }
+            return node;
+        }
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 179 /* PropertyAccessExpression */:
+                    return substitutePropertyAccessExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return substituteElementAccessExpression(node);
+                case 181 /* CallExpression */:
+                    return substituteCallExpression(node);
+            }
+            return node;
+        }
+        function substitutePropertyAccessExpression(node) {
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node);
+            }
+            return node;
+        }
+        function substituteElementAccessExpression(node) {
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                return createSuperAccessInAsyncMethod(node.argumentExpression, node);
+            }
+            return node;
+        }
+        function substituteCallExpression(node) {
+            var expression = node.expression;
+            if (ts.isSuperProperty(expression)) {
+                var argumentExpression = ts.isPropertyAccessExpression(expression)
+                    ? substitutePropertyAccessExpression(expression)
+                    : substituteElementAccessExpression(expression);
+                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
+                /*typeArguments*/ undefined, [
+                    ts.createThis()
+                ].concat(node.arguments));
+            }
+            return node;
+        }
+        function isSuperContainer(node) {
+            var kind = node.kind;
+            return kind === 229 /* ClassDeclaration */
+                || kind === 152 /* Constructor */
+                || kind === 151 /* MethodDeclaration */
+                || kind === 153 /* GetAccessor */
+                || kind === 154 /* SetAccessor */;
+        }
+        function createSuperAccessInAsyncMethod(argumentExpression, location) {
+            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
+                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), 
+                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
+            }
+            else {
+                return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), 
+                /*typeArguments*/ undefined, [argumentExpression]), location);
+            }
+        }
+    }
+    ts.transformES2017 = transformES2017;
+    var awaiterHelper = {
+        name: "typescript:awaiter",
+        scoped: false,
+        priority: 5,
+        text: "\n            var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n                return new (P || (P = Promise))(function (resolve, reject) {\n                    function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n                    function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n                    function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n                    step((generator = generator.apply(thisArg, _arguments || [])).next());\n                });\n            };"
+    };
+    function createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, body) {
+        context.requestEmitHelper(awaiterHelper);
+        var generatorFunc = ts.createFunctionExpression(
+        /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), 
+        /*name*/ undefined, 
+        /*typeParameters*/ undefined, 
+        /*parameters*/ [], 
+        /*type*/ undefined, body);
+        // Mark this node as originally an async function
+        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
+        return ts.createCall(ts.getHelperName("__awaiter"), 
+        /*typeArguments*/ undefined, [
+            ts.createThis(),
+            hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(),
+            promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(),
+            generatorFunc
+        ]);
+    }
+    ts.asyncSuperHelper = {
+        name: "typescript:async-super",
+        scoped: true,
+        text: "\n            const _super = name => super[name];\n        "
+    };
+    ts.advancedAsyncSuperHelper = {
+        name: "typescript:advanced-async-super",
+        scoped: true,
+        text: "\n            const _super = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);\n        "
+    };
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/// <reference path="es2017.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    var ESNextSubstitutionFlags;
+    (function (ESNextSubstitutionFlags) {
+        /** Enables substitutions for async methods with `super` calls. */
+        ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
+    })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {}));
+    function transformESNext(context) {
+        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var resolver = context.getEmitResolver();
+        var compilerOptions = context.getCompilerOptions();
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var previousOnEmitNode = context.onEmitNode;
+        context.onEmitNode = onEmitNode;
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        context.onSubstituteNode = onSubstituteNode;
+        var enabledSubstitutions;
+        var enclosingFunctionFlags;
+        var enclosingSuperContainerFlags = 0;
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            var visited = ts.visitEachChild(node, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        }
+        function visitor(node) {
+            return visitorWorker(node, /*noDestructuringValue*/ false);
+        }
+        function visitorNoDestructuringValue(node) {
+            return visitorWorker(node, /*noDestructuringValue*/ true);
+        }
+        function visitorNoAsyncModifier(node) {
+            if (node.kind === 120 /* AsyncKeyword */) {
+                return undefined;
+            }
+            return node;
+        }
+        function visitorWorker(node, noDestructuringValue) {
+            if ((node.transformFlags & 8 /* ContainsESNext */) === 0) {
+                return node;
+            }
+            switch (node.kind) {
+                case 191 /* AwaitExpression */:
+                    return visitAwaitExpression(node);
+                case 197 /* YieldExpression */:
+                    return visitYieldExpression(node);
+                case 222 /* LabeledStatement */:
+                    return visitLabeledStatement(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return visitObjectLiteralExpression(node);
+                case 194 /* BinaryExpression */:
+                    return visitBinaryExpression(node, noDestructuringValue);
+                case 226 /* VariableDeclaration */:
+                    return visitVariableDeclaration(node);
+                case 216 /* ForOfStatement */:
+                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
+                case 214 /* ForStatement */:
+                    return visitForStatement(node);
+                case 190 /* VoidExpression */:
+                    return visitVoidExpression(node);
+                case 152 /* Constructor */:
+                    return visitConstructorDeclaration(node);
+                case 151 /* MethodDeclaration */:
+                    return visitMethodDeclaration(node);
+                case 153 /* GetAccessor */:
+                    return visitGetAccessorDeclaration(node);
+                case 154 /* SetAccessor */:
+                    return visitSetAccessorDeclaration(node);
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 186 /* FunctionExpression */:
+                    return visitFunctionExpression(node);
+                case 187 /* ArrowFunction */:
+                    return visitArrowFunction(node);
+                case 146 /* Parameter */:
+                    return visitParameter(node);
+                case 210 /* ExpressionStatement */:
+                    return visitExpressionStatement(node);
+                case 185 /* ParenthesizedExpression */:
+                    return visitParenthesizedExpression(node, noDestructuringValue);
+                case 260 /* CatchClause */:
+                    return visitCatchClause(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function visitAwaitExpression(node) {
+            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
+                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), 
+                /*location*/ node), node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitYieldExpression(node) {
+            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ && node.asteriskToken) {
+                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitLabeledStatement(node) {
+            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
+                var statement = ts.unwrapInnermostStatementOfLabel(node);
+                if (statement.kind === 216 /* ForOfStatement */ && statement.awaitModifier) {
+                    return visitForOfStatement(statement, node);
+                }
+                return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function chunkObjectLiteralElements(elements) {
+            var chunkObject;
+            var objects = [];
+            for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) {
+                var e = elements_3[_i];
+                if (e.kind === 263 /* SpreadAssignment */) {
+                    if (chunkObject) {
+                        objects.push(ts.createObjectLiteral(chunkObject));
+                        chunkObject = undefined;
+                    }
+                    var target = e.expression;
+                    objects.push(ts.visitNode(target, visitor, ts.isExpression));
+                }
+                else {
+                    if (!chunkObject) {
+                        chunkObject = [];
+                    }
+                    if (e.kind === 261 /* PropertyAssignment */) {
+                        var p = e;
+                        chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
+                    }
+                    else {
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
+                    }
+                }
+            }
+            if (chunkObject) {
+                objects.push(ts.createObjectLiteral(chunkObject));
+            }
+            return objects;
+        }
+        function visitObjectLiteralExpression(node) {
+            if (node.transformFlags & 1048576 /* ContainsObjectSpread */) {
+                // spread elements emit like so:
+                // non-spread elements are chunked together into object literals, and then all are passed to __assign:
+                //     { a, ...o, b } => __assign({a}, o, {b});
+                // If the first element is a spread element, then the first argument to __assign is {}:
+                //     { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
+                var objects = chunkObjectLiteralElements(node.properties);
+                if (objects.length && objects[0].kind !== 178 /* ObjectLiteralExpression */) {
+                    objects.unshift(ts.createObjectLiteral());
+                }
+                return createAssignHelper(context, objects);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitExpressionStatement(node) {
+            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
+        }
+        function visitParenthesizedExpression(node, noDestructuringValue) {
+            return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
+        }
+        function visitCatchClause(node) {
+            if (!node.variableDeclaration) {
+                return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock));
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a BinaryExpression that contains a destructuring assignment.
+         *
+         * @param node A BinaryExpression node.
+         */
+        function visitBinaryExpression(node, noDestructuringValue) {
+            if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576 /* ContainsObjectRest */) {
+                return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue);
+            }
+            else if (node.operatorToken.kind === 26 /* CommaToken */) {
+                return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression));
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a VariableDeclaration node with a binding pattern.
+         *
+         * @param node A VariableDeclaration node.
+         */
+        function visitVariableDeclaration(node) {
+            // If we are here it is because the name contains a binding pattern with a rest somewhere in it.
+            if (ts.isBindingPattern(node.name) && node.name.transformFlags & 1048576 /* ContainsObjectRest */) {
+                return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitForStatement(node) {
+            return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement));
+        }
+        function visitVoidExpression(node) {
+            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
+        }
+        /**
+         * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
+         *
+         * @param node A ForOfStatement.
+         */
+        function visitForOfStatement(node, outermostLabeledStatement) {
+            if (node.initializer.transformFlags & 1048576 /* ContainsObjectRest */) {
+                node = transformForOfStatementWithObjectRest(node);
+            }
+            if (node.awaitModifier) {
+                return transformForAwaitOfStatement(node, outermostLabeledStatement);
+            }
+            else {
+                return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement);
+            }
+        }
+        function transformForOfStatementWithObjectRest(node) {
+            var initializerWithoutParens = ts.skipParentheses(node.initializer);
+            if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) {
+                var bodyLocation = void 0;
+                var statementsLocation = void 0;
+                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
+                var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)];
+                if (ts.isBlock(node.statement)) {
+                    ts.addRange(statements, node.statement.statements);
+                    bodyLocation = node.statement;
+                    statementsLocation = node.statement.statements;
+                }
+                return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([
+                    ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer)
+                ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
+                /*multiLine*/ true), bodyLocation));
+            }
+            return node;
+        }
+        function convertForOfStatementHead(node, boundValue) {
+            var binding = ts.createForOfBindingStatement(node.initializer, boundValue);
+            var bodyLocation;
+            var statementsLocation;
+            var statements = [ts.visitNode(binding, visitor, ts.isStatement)];
+            var statement = ts.visitNode(node.statement, visitor, ts.isStatement);
+            if (ts.isBlock(statement)) {
+                ts.addRange(statements, statement.statements);
+                bodyLocation = statement;
+                statementsLocation = statement.statements;
+            }
+            else {
+                statements.push(statement);
+            }
+            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
+            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
+        }
+        function createDownlevelAwait(expression) {
+            return enclosingFunctionFlags & 1 /* Generator */
+                ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression))
+                : ts.createAwait(expression);
+        }
+        function transformForAwaitOfStatement(node, outermostLabeledStatement) {
+            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var errorRecord = ts.createUniqueName("e");
+            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
+            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
+            var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
+            var getDone = ts.createPropertyAccess(result, "done");
+            var getValue = ts.createPropertyAccess(result, "value");
+            var callReturn = ts.createFunctionCall(returnMethod, iterator, []);
+            hoistVariableDeclaration(errorRecord);
+            hoistVariableDeclaration(returnMethod);
+            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
+            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
+                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, callValues), node.expression),
+                ts.createVariableDeclaration(result)
+            ]), node.expression), 2097152 /* NoHoisting */), 
+            /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), 
+            /*incrementor*/ undefined, 
+            /*statement*/ convertForOfStatementHead(node, createDownlevelAwait(getValue))), 
+            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
+            return ts.createTry(ts.createBlock([
+                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement)
+            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
+                ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
+                    ts.createPropertyAssignment("error", catchVariable)
+                ])))
+            ]), 1 /* SingleLine */)), ts.createBlock([
+                ts.createTry(
+                /*tryBlock*/ ts.createBlock([
+                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */)
+                ]), 
+                /*catchClause*/ undefined, 
+                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
+                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
+                ]), 1 /* SingleLine */))
+            ]));
+        }
+        function visitParameter(node) {
+            if (node.transformFlags & 1048576 /* ContainsObjectRest */) {
+                // Binding patterns are converted into a generated name and are
+                // evaluated inside the function body.
+                return ts.updateParameter(node, 
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), 
+                /*questionToken*/ undefined, 
+                /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitConstructorDeclaration(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = 0 /* Normal */;
+            var updated = ts.updateConstructor(node, 
+            /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitGetAccessorDeclaration(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = 0 /* Normal */;
+            var updated = ts.updateGetAccessor(node, 
+            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitSetAccessorDeclaration(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = 0 /* Normal */;
+            var updated = ts.updateSetAccessor(node, 
+            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitMethodDeclaration(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = ts.getFunctionFlags(node);
+            var updated = ts.updateMethod(node, 
+            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
+                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
+                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
+                ? undefined
+                : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
+                ? transformAsyncGeneratorFunctionBody(node)
+                : transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitFunctionDeclaration(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = ts.getFunctionFlags(node);
+            var updated = ts.updateFunctionDeclaration(node, 
+            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
+                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
+                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
+                ? undefined
+                : node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
+                ? transformAsyncGeneratorFunctionBody(node)
+                : transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitArrowFunction(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = ts.getFunctionFlags(node);
+            var updated = ts.updateArrowFunction(node, node.modifiers, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function visitFunctionExpression(node) {
+            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
+            enclosingFunctionFlags = ts.getFunctionFlags(node);
+            var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */
+                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
+                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
+                ? undefined
+                : node.asteriskToken, node.name, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
+                ? transformAsyncGeneratorFunctionBody(node)
+                : transformFunctionBody(node));
+            enclosingFunctionFlags = savedEnclosingFunctionFlags;
+            return updated;
+        }
+        function transformAsyncGeneratorFunctionBody(node) {
+            resumeLexicalEnvironment();
+            var statements = [];
+            var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
+            appendObjectRestAssignmentsIfNeeded(statements, node);
+            statements.push(ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression(
+            /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), 
+            /*typeParameters*/ undefined, 
+            /*parameters*/ [], 
+            /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset))))));
+            ts.addRange(statements, endLexicalEnvironment());
+            var block = ts.updateBlock(node.body, statements);
+            // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
+            // This step isn't needed if we eventually transform this to ES5.
+            if (languageVersion >= 2 /* ES2015 */) {
+                if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
+                    enableSubstitutionForAsyncMethodsWithSuper();
+                    ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
+                }
+                else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
+                    enableSubstitutionForAsyncMethodsWithSuper();
+                    ts.addEmitHelper(block, ts.asyncSuperHelper);
+                }
+            }
+            return block;
+        }
+        function transformFunctionBody(node) {
+            resumeLexicalEnvironment();
+            var statementOffset = 0;
+            var statements = [];
+            var body = ts.visitNode(node.body, visitor, ts.isConciseBody);
+            if (ts.isBlock(body)) {
+                statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
+            }
+            ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
+            var trailingStatements = endLexicalEnvironment();
+            if (statementOffset > 0 || ts.some(statements) || ts.some(trailingStatements)) {
+                var block = ts.convertToFunctionBody(body, /*multiLine*/ true);
+                ts.addRange(statements, block.statements.slice(statementOffset));
+                ts.addRange(statements, trailingStatements);
+                return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements));
+            }
+            return body;
+        }
+        function appendObjectRestAssignmentsIfNeeded(statements, node) {
+            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
+                var parameter = _a[_i];
+                if (parameter.transformFlags & 1048576 /* ContainsObjectRest */) {
+                    var temp = ts.getGeneratedNameForNode(parameter);
+                    var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, 
+                    /*doNotRecordTempVariablesInLine*/ false, 
+                    /*skipInitializer*/ true);
+                    if (ts.some(declarations)) {
+                        var statement = ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations));
+                        ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
+                        statements = ts.append(statements, statement);
+                    }
+                }
+            }
+            return statements;
+        }
+        function enableSubstitutionForAsyncMethodsWithSuper() {
+            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
+                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
+                // We need to enable substitutions for call, property access, and element access
+                // if we need to rewrite super calls.
+                context.enableSubstitution(181 /* CallExpression */);
+                context.enableSubstitution(179 /* PropertyAccessExpression */);
+                context.enableSubstitution(180 /* ElementAccessExpression */);
+                // We need to be notified when entering and exiting declarations that bind super.
+                context.enableEmitNotification(229 /* ClassDeclaration */);
+                context.enableEmitNotification(151 /* MethodDeclaration */);
+                context.enableEmitNotification(153 /* GetAccessor */);
+                context.enableEmitNotification(154 /* SetAccessor */);
+                context.enableEmitNotification(152 /* Constructor */);
+            }
+        }
+        /**
+         * Called by the printer just before a node is printed.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to be printed.
+         * @param emitCallback The callback used to emit the node.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            // If we need to support substitutions for `super` in an async method,
+            // we should track it here.
+            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
+                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
+                if (superContainerFlags !== enclosingSuperContainerFlags) {
+                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
+                    enclosingSuperContainerFlags = superContainerFlags;
+                    previousOnEmitNode(hint, node, emitCallback);
+                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
+                    return;
+                }
+            }
+            previousOnEmitNode(hint, node, emitCallback);
+        }
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint The context for the emitter.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
+                return substituteExpression(node);
+            }
+            return node;
+        }
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 179 /* PropertyAccessExpression */:
+                    return substitutePropertyAccessExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return substituteElementAccessExpression(node);
+                case 181 /* CallExpression */:
+                    return substituteCallExpression(node);
+            }
+            return node;
+        }
+        function substitutePropertyAccessExpression(node) {
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node);
+            }
+            return node;
+        }
+        function substituteElementAccessExpression(node) {
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                return createSuperAccessInAsyncMethod(node.argumentExpression, node);
+            }
+            return node;
+        }
+        function substituteCallExpression(node) {
+            var expression = node.expression;
+            if (ts.isSuperProperty(expression)) {
+                var argumentExpression = ts.isPropertyAccessExpression(expression)
+                    ? substitutePropertyAccessExpression(expression)
+                    : substituteElementAccessExpression(expression);
+                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
+                /*typeArguments*/ undefined, [
+                    ts.createThis()
+                ].concat(node.arguments));
+            }
+            return node;
+        }
+        function isSuperContainer(node) {
+            var kind = node.kind;
+            return kind === 229 /* ClassDeclaration */
+                || kind === 152 /* Constructor */
+                || kind === 151 /* MethodDeclaration */
+                || kind === 153 /* GetAccessor */
+                || kind === 154 /* SetAccessor */;
+        }
+        function createSuperAccessInAsyncMethod(argumentExpression, location) {
+            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
+                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), 
+                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
+            }
+            else {
+                return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), 
+                /*typeArguments*/ undefined, [argumentExpression]), location);
+            }
+        }
+    }
+    ts.transformESNext = transformESNext;
+    var assignHelper = {
+        name: "typescript:assign",
+        scoped: false,
+        priority: 1,
+        text: "\n            var __assign = (this && this.__assign) || Object.assign || function(t) {\n                for (var s, i = 1, n = arguments.length; i < n; i++) {\n                    s = arguments[i];\n                    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                        t[p] = s[p];\n                }\n                return t;\n            };"
+    };
+    function createAssignHelper(context, attributesSegments) {
+        if (context.getCompilerOptions().target >= 2 /* ES2015 */) {
+            return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), 
+            /*typeArguments*/ undefined, attributesSegments);
+        }
+        context.requestEmitHelper(assignHelper);
+        return ts.createCall(ts.getHelperName("__assign"), 
+        /*typeArguments*/ undefined, attributesSegments);
+    }
+    ts.createAssignHelper = createAssignHelper;
+    var awaitHelper = {
+        name: "typescript:await",
+        scoped: false,
+        text: "\n            var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\n        "
+    };
+    function createAwaitHelper(context, expression) {
+        context.requestEmitHelper(awaitHelper);
+        return ts.createCall(ts.getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
+    }
+    var asyncGeneratorHelper = {
+        name: "typescript:asyncGenerator",
+        scoped: false,
+        text: "\n            var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var g = generator.apply(thisArg, _arguments || []), i, q = [];\n                return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n                function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n                function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n                function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);  }\n                function fulfill(value) { resume(\"next\", value); }\n                function reject(value) { resume(\"throw\", value); }\n                function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n            };\n        "
+    };
+    function createAsyncGeneratorHelper(context, generatorFunc) {
+        context.requestEmitHelper(awaitHelper);
+        context.requestEmitHelper(asyncGeneratorHelper);
+        // Mark this node as originally an async function
+        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */;
+        return ts.createCall(ts.getHelperName("__asyncGenerator"), 
+        /*typeArguments*/ undefined, [
+            ts.createThis(),
+            ts.createIdentifier("arguments"),
+            generatorFunc
+        ]);
+    }
+    var asyncDelegator = {
+        name: "typescript:asyncDelegator",
+        scoped: false,
+        text: "\n            var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n                var i, p;\n                return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n                function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; }; }\n            };\n        "
+    };
+    function createAsyncDelegatorHelper(context, expression, location) {
+        context.requestEmitHelper(awaitHelper);
+        context.requestEmitHelper(asyncDelegator);
+        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncDelegator"), 
+        /*typeArguments*/ undefined, [expression]), location);
+    }
+    var asyncValues = {
+        name: "typescript:asyncValues",
+        scoped: false,
+        text: "\n            var __asyncValues = (this && this.__asyncIterator) || function (o) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var m = o[Symbol.asyncIterator];\n                return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\n            };\n        "
+    };
+    function createAsyncValuesHelper(context, expression, location) {
+        context.requestEmitHelper(asyncValues);
+        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncValues"), 
+        /*typeArguments*/ undefined, [expression]), location);
+    }
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/// <reference path="./esnext.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    function transformJsx(context) {
+        var compilerOptions = context.getCompilerOptions();
+        return transformSourceFile;
+        /**
+         * Transform JSX-specific syntax in a SourceFile.
+         *
+         * @param node A SourceFile node.
+         */
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            var visited = ts.visitEachChild(node, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        }
+        function visitor(node) {
+            if (node.transformFlags & 4 /* ContainsJsx */) {
+                return visitorWorker(node);
+            }
+            else {
+                return node;
+            }
+        }
+        function visitorWorker(node) {
+            switch (node.kind) {
+                case 249 /* JsxElement */:
+                    return visitJsxElement(node, /*isChild*/ false);
+                case 250 /* JsxSelfClosingElement */:
+                    return visitJsxSelfClosingElement(node, /*isChild*/ false);
+                case 256 /* JsxExpression */:
+                    return visitJsxExpression(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function transformJsxChildToExpression(node) {
+            switch (node.kind) {
+                case 10 /* JsxText */:
+                    return visitJsxText(node);
+                case 256 /* JsxExpression */:
+                    return visitJsxExpression(node);
+                case 249 /* JsxElement */:
+                    return visitJsxElement(node, /*isChild*/ true);
+                case 250 /* JsxSelfClosingElement */:
+                    return visitJsxSelfClosingElement(node, /*isChild*/ true);
+                default:
+                    ts.Debug.failBadSyntaxKind(node);
+                    return undefined;
+            }
+        }
+        function visitJsxElement(node, isChild) {
+            return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
+        }
+        function visitJsxSelfClosingElement(node, isChild) {
+            return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
+        }
+        function visitJsxOpeningLikeElement(node, children, isChild, location) {
+            var tagName = getTagName(node);
+            var objectProperties;
+            var attrs = node.attributes.properties;
+            if (attrs.length === 0) {
+                // When there are no attributes, React wants "null"
+                objectProperties = ts.createNull();
+            }
+            else {
+                // Map spans of JsxAttribute nodes into object literals and spans
+                // of JsxSpreadAttribute nodes into expressions.
+                var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread
+                    ? ts.map(attrs, transformJsxSpreadAttributeToExpression)
+                    : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); }));
+                if (ts.isJsxSpreadAttribute(attrs[0])) {
+                    // We must always emit at least one object literal before a spread
+                    // argument.
+                    segments.unshift(ts.createObjectLiteral());
+                }
+                // Either emit one big object literal (no spread attribs), or
+                // a call to the __assign helper.
+                objectProperties = ts.singleOrUndefined(segments);
+                if (!objectProperties) {
+                    objectProperties = ts.createAssignHelper(context, segments);
+                }
+            }
+            var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location);
+            if (isChild) {
+                ts.startOnNewLine(element);
+            }
+            return element;
+        }
+        function transformJsxSpreadAttributeToExpression(node) {
+            return ts.visitNode(node.expression, visitor, ts.isExpression);
+        }
+        function transformJsxAttributeToObjectLiteralElement(node) {
+            var name = getAttributeName(node);
+            var expression = transformJsxAttributeInitializer(node.initializer);
+            return ts.createPropertyAssignment(name, expression);
+        }
+        function transformJsxAttributeInitializer(node) {
+            if (node === undefined) {
+                return ts.createTrue();
+            }
+            else if (node.kind === 9 /* StringLiteral */) {
+                var decoded = tryDecodeEntities(node.text);
+                return decoded ? ts.setTextRange(ts.createLiteral(decoded), node) : node;
+            }
+            else if (node.kind === 256 /* JsxExpression */) {
+                if (node.expression === undefined) {
+                    return ts.createTrue();
+                }
+                return visitJsxExpression(node);
+            }
+            else {
+                ts.Debug.failBadSyntaxKind(node);
+            }
+        }
+        function visitJsxText(node) {
+            var fixed = fixupWhitespaceAndDecodeEntities(ts.getTextOfNode(node, /*includeTrivia*/ true));
+            return fixed === undefined ? undefined : ts.createLiteral(fixed);
+        }
+        /**
+         * JSX trims whitespace at the end and beginning of lines, except that the
+         * start/end of a tag is considered a start/end of a line only if that line is
+         * on the same line as the closing tag. See examples in
+         * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
+         * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
+         *
+         * An equivalent algorithm would be:
+         * - If there is only one line, return it.
+         * - If there is only whitespace (but multiple lines), return `undefined`.
+         * - Split the text into lines.
+         * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines.
+         * - Decode entities on each line (individually).
+         * - Remove empty lines and join the rest with " ".
+         */
+        function fixupWhitespaceAndDecodeEntities(text) {
+            var acc;
+            // First non-whitespace character on this line.
+            var firstNonWhitespace = 0;
+            // Last non-whitespace character on this line.
+            var lastNonWhitespace = -1;
+            // These initial values are special because the first line is:
+            // firstNonWhitespace = 0 to indicate that we want leading whitsepace,
+            // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace.
+            for (var i = 0; i < text.length; i++) {
+                var c = text.charCodeAt(i);
+                if (ts.isLineBreak(c)) {
+                    // If we've seen any non-whitespace characters on this line, add the 'trim' of the line.
+                    // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.)
+                    if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
+                        acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
+                    }
+                    // Reset firstNonWhitespace for the next line.
+                    // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1.
+                    firstNonWhitespace = -1;
+                }
+                else if (!ts.isWhiteSpaceSingleLine(c)) {
+                    lastNonWhitespace = i;
+                    if (firstNonWhitespace === -1) {
+                        firstNonWhitespace = i;
+                    }
+                }
+            }
+            return firstNonWhitespace !== -1
+                // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace.
+                ? addLineOfJsxText(acc, text.substr(firstNonWhitespace))
+                // Last line was all whitespace, so ignore it
+                : acc;
+        }
+        function addLineOfJsxText(acc, trimmedLine) {
+            // We do not escape the string here as that is handled by the printer
+            // when it emits the literal. We do, however, need to decode JSX entities.
+            var decoded = decodeEntities(trimmedLine);
+            return acc === undefined ? decoded : acc + " " + decoded;
+        }
+        /**
+         * Replace entities like "&nbsp;", "&#123;", and "&#xDEADBEEF;" with the characters they encode.
+         * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
+         */
+        function decodeEntities(text) {
+            return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) {
+                if (decimal) {
+                    return String.fromCharCode(parseInt(decimal, 10));
+                }
+                else if (hex) {
+                    return String.fromCharCode(parseInt(hex, 16));
+                }
+                else {
+                    var ch = entities.get(word);
+                    // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
+                    return ch ? String.fromCharCode(ch) : match;
+                }
+            });
+        }
+        /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
+        function tryDecodeEntities(text) {
+            var decoded = decodeEntities(text);
+            return decoded === text ? undefined : decoded;
+        }
+        function getTagName(node) {
+            if (node.kind === 249 /* JsxElement */) {
+                return getTagName(node.openingElement);
+            }
+            else {
+                var name = node.tagName;
+                if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) {
+                    return ts.createLiteral(ts.idText(name));
+                }
+                else {
+                    return ts.createExpressionFromEntityName(name);
+                }
+            }
+        }
+        /**
+         * Emit an attribute name, which is quoted if it needs to be quoted. Because
+         * these emit into an object literal property name, we don't need to be worried
+         * about keywords, just non-identifier characters
+         */
+        function getAttributeName(node) {
+            var name = node.name;
+            var text = ts.idText(name);
+            if (/^[A-Za-z_]\w*$/.test(text)) {
+                return name;
+            }
+            else {
+                return ts.createLiteral(text);
+            }
+        }
+        function visitJsxExpression(node) {
+            return ts.visitNode(node.expression, visitor, ts.isExpression);
+        }
+    }
+    ts.transformJsx = transformJsx;
+    var entities = ts.createMapFromTemplate({
+        "quot": 0x0022,
+        "amp": 0x0026,
+        "apos": 0x0027,
+        "lt": 0x003C,
+        "gt": 0x003E,
+        "nbsp": 0x00A0,
+        "iexcl": 0x00A1,
+        "cent": 0x00A2,
+        "pound": 0x00A3,
+        "curren": 0x00A4,
+        "yen": 0x00A5,
+        "brvbar": 0x00A6,
+        "sect": 0x00A7,
+        "uml": 0x00A8,
+        "copy": 0x00A9,
+        "ordf": 0x00AA,
+        "laquo": 0x00AB,
+        "not": 0x00AC,
+        "shy": 0x00AD,
+        "reg": 0x00AE,
+        "macr": 0x00AF,
+        "deg": 0x00B0,
+        "plusmn": 0x00B1,
+        "sup2": 0x00B2,
+        "sup3": 0x00B3,
+        "acute": 0x00B4,
+        "micro": 0x00B5,
+        "para": 0x00B6,
+        "middot": 0x00B7,
+        "cedil": 0x00B8,
+        "sup1": 0x00B9,
+        "ordm": 0x00BA,
+        "raquo": 0x00BB,
+        "frac14": 0x00BC,
+        "frac12": 0x00BD,
+        "frac34": 0x00BE,
+        "iquest": 0x00BF,
+        "Agrave": 0x00C0,
+        "Aacute": 0x00C1,
+        "Acirc": 0x00C2,
+        "Atilde": 0x00C3,
+        "Auml": 0x00C4,
+        "Aring": 0x00C5,
+        "AElig": 0x00C6,
+        "Ccedil": 0x00C7,
+        "Egrave": 0x00C8,
+        "Eacute": 0x00C9,
+        "Ecirc": 0x00CA,
+        "Euml": 0x00CB,
+        "Igrave": 0x00CC,
+        "Iacute": 0x00CD,
+        "Icirc": 0x00CE,
+        "Iuml": 0x00CF,
+        "ETH": 0x00D0,
+        "Ntilde": 0x00D1,
+        "Ograve": 0x00D2,
+        "Oacute": 0x00D3,
+        "Ocirc": 0x00D4,
+        "Otilde": 0x00D5,
+        "Ouml": 0x00D6,
+        "times": 0x00D7,
+        "Oslash": 0x00D8,
+        "Ugrave": 0x00D9,
+        "Uacute": 0x00DA,
+        "Ucirc": 0x00DB,
+        "Uuml": 0x00DC,
+        "Yacute": 0x00DD,
+        "THORN": 0x00DE,
+        "szlig": 0x00DF,
+        "agrave": 0x00E0,
+        "aacute": 0x00E1,
+        "acirc": 0x00E2,
+        "atilde": 0x00E3,
+        "auml": 0x00E4,
+        "aring": 0x00E5,
+        "aelig": 0x00E6,
+        "ccedil": 0x00E7,
+        "egrave": 0x00E8,
+        "eacute": 0x00E9,
+        "ecirc": 0x00EA,
+        "euml": 0x00EB,
+        "igrave": 0x00EC,
+        "iacute": 0x00ED,
+        "icirc": 0x00EE,
+        "iuml": 0x00EF,
+        "eth": 0x00F0,
+        "ntilde": 0x00F1,
+        "ograve": 0x00F2,
+        "oacute": 0x00F3,
+        "ocirc": 0x00F4,
+        "otilde": 0x00F5,
+        "ouml": 0x00F6,
+        "divide": 0x00F7,
+        "oslash": 0x00F8,
+        "ugrave": 0x00F9,
+        "uacute": 0x00FA,
+        "ucirc": 0x00FB,
+        "uuml": 0x00FC,
+        "yacute": 0x00FD,
+        "thorn": 0x00FE,
+        "yuml": 0x00FF,
+        "OElig": 0x0152,
+        "oelig": 0x0153,
+        "Scaron": 0x0160,
+        "scaron": 0x0161,
+        "Yuml": 0x0178,
+        "fnof": 0x0192,
+        "circ": 0x02C6,
+        "tilde": 0x02DC,
+        "Alpha": 0x0391,
+        "Beta": 0x0392,
+        "Gamma": 0x0393,
+        "Delta": 0x0394,
+        "Epsilon": 0x0395,
+        "Zeta": 0x0396,
+        "Eta": 0x0397,
+        "Theta": 0x0398,
+        "Iota": 0x0399,
+        "Kappa": 0x039A,
+        "Lambda": 0x039B,
+        "Mu": 0x039C,
+        "Nu": 0x039D,
+        "Xi": 0x039E,
+        "Omicron": 0x039F,
+        "Pi": 0x03A0,
+        "Rho": 0x03A1,
+        "Sigma": 0x03A3,
+        "Tau": 0x03A4,
+        "Upsilon": 0x03A5,
+        "Phi": 0x03A6,
+        "Chi": 0x03A7,
+        "Psi": 0x03A8,
+        "Omega": 0x03A9,
+        "alpha": 0x03B1,
+        "beta": 0x03B2,
+        "gamma": 0x03B3,
+        "delta": 0x03B4,
+        "epsilon": 0x03B5,
+        "zeta": 0x03B6,
+        "eta": 0x03B7,
+        "theta": 0x03B8,
+        "iota": 0x03B9,
+        "kappa": 0x03BA,
+        "lambda": 0x03BB,
+        "mu": 0x03BC,
+        "nu": 0x03BD,
+        "xi": 0x03BE,
+        "omicron": 0x03BF,
+        "pi": 0x03C0,
+        "rho": 0x03C1,
+        "sigmaf": 0x03C2,
+        "sigma": 0x03C3,
+        "tau": 0x03C4,
+        "upsilon": 0x03C5,
+        "phi": 0x03C6,
+        "chi": 0x03C7,
+        "psi": 0x03C8,
+        "omega": 0x03C9,
+        "thetasym": 0x03D1,
+        "upsih": 0x03D2,
+        "piv": 0x03D6,
+        "ensp": 0x2002,
+        "emsp": 0x2003,
+        "thinsp": 0x2009,
+        "zwnj": 0x200C,
+        "zwj": 0x200D,
+        "lrm": 0x200E,
+        "rlm": 0x200F,
+        "ndash": 0x2013,
+        "mdash": 0x2014,
+        "lsquo": 0x2018,
+        "rsquo": 0x2019,
+        "sbquo": 0x201A,
+        "ldquo": 0x201C,
+        "rdquo": 0x201D,
+        "bdquo": 0x201E,
+        "dagger": 0x2020,
+        "Dagger": 0x2021,
+        "bull": 0x2022,
+        "hellip": 0x2026,
+        "permil": 0x2030,
+        "prime": 0x2032,
+        "Prime": 0x2033,
+        "lsaquo": 0x2039,
+        "rsaquo": 0x203A,
+        "oline": 0x203E,
+        "frasl": 0x2044,
+        "euro": 0x20AC,
+        "image": 0x2111,
+        "weierp": 0x2118,
+        "real": 0x211C,
+        "trade": 0x2122,
+        "alefsym": 0x2135,
+        "larr": 0x2190,
+        "uarr": 0x2191,
+        "rarr": 0x2192,
+        "darr": 0x2193,
+        "harr": 0x2194,
+        "crarr": 0x21B5,
+        "lArr": 0x21D0,
+        "uArr": 0x21D1,
+        "rArr": 0x21D2,
+        "dArr": 0x21D3,
+        "hArr": 0x21D4,
+        "forall": 0x2200,
+        "part": 0x2202,
+        "exist": 0x2203,
+        "empty": 0x2205,
+        "nabla": 0x2207,
+        "isin": 0x2208,
+        "notin": 0x2209,
+        "ni": 0x220B,
+        "prod": 0x220F,
+        "sum": 0x2211,
+        "minus": 0x2212,
+        "lowast": 0x2217,
+        "radic": 0x221A,
+        "prop": 0x221D,
+        "infin": 0x221E,
+        "ang": 0x2220,
+        "and": 0x2227,
+        "or": 0x2228,
+        "cap": 0x2229,
+        "cup": 0x222A,
+        "int": 0x222B,
+        "there4": 0x2234,
+        "sim": 0x223C,
+        "cong": 0x2245,
+        "asymp": 0x2248,
+        "ne": 0x2260,
+        "equiv": 0x2261,
+        "le": 0x2264,
+        "ge": 0x2265,
+        "sub": 0x2282,
+        "sup": 0x2283,
+        "nsub": 0x2284,
+        "sube": 0x2286,
+        "supe": 0x2287,
+        "oplus": 0x2295,
+        "otimes": 0x2297,
+        "perp": 0x22A5,
+        "sdot": 0x22C5,
+        "lceil": 0x2308,
+        "rceil": 0x2309,
+        "lfloor": 0x230A,
+        "rfloor": 0x230B,
+        "lang": 0x2329,
+        "rang": 0x232A,
+        "loz": 0x25CA,
+        "spades": 0x2660,
+        "clubs": 0x2663,
+        "hearts": 0x2665,
+        "diams": 0x2666
+    });
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    function transformES2016(context) {
+        var hoistVariableDeclaration = context.hoistVariableDeclaration;
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitor(node) {
+            if ((node.transformFlags & 32 /* ContainsES2016 */) === 0) {
+                return node;
+            }
+            switch (node.kind) {
+                case 194 /* BinaryExpression */:
+                    return visitBinaryExpression(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function visitBinaryExpression(node) {
+            switch (node.operatorToken.kind) {
+                case 62 /* AsteriskAsteriskEqualsToken */:
+                    return visitExponentiationAssignmentExpression(node);
+                case 40 /* AsteriskAsteriskToken */:
+                    return visitExponentiationExpression(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function visitExponentiationAssignmentExpression(node) {
+            var target;
+            var value;
+            var left = ts.visitNode(node.left, visitor, ts.isExpression);
+            var right = ts.visitNode(node.right, visitor, ts.isExpression);
+            if (ts.isElementAccessExpression(left)) {
+                // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
+                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
+                var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration);
+                target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left);
+                value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left);
+            }
+            else if (ts.isPropertyAccessExpression(left)) {
+                // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
+                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
+                target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left);
+                value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left);
+            }
+            else {
+                // Transforms `a **= b` into `a = Math.pow(a, b)`
+                target = left;
+                value = left;
+            }
+            return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node);
+        }
+        function visitExponentiationExpression(node) {
+            // Transforms `a ** b` into `Math.pow(a, b)`
+            var left = ts.visitNode(node.left, visitor, ts.isExpression);
+            var right = ts.visitNode(node.right, visitor, ts.isExpression);
+            return ts.createMathPow(left, right, /*location*/ node);
+        }
+    }
+    ts.transformES2016 = transformES2016;
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/// <reference path="./destructuring.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    var ES2015SubstitutionFlags;
+    (function (ES2015SubstitutionFlags) {
+        /** Enables substitutions for captured `this` */
+        ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis";
+        /** Enables substitutions for block-scoped bindings. */
+        ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings";
+    })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {}));
+    var CopyDirection;
+    (function (CopyDirection) {
+        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
+        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
+    })(CopyDirection || (CopyDirection = {}));
+    var Jump;
+    (function (Jump) {
+        Jump[Jump["Break"] = 2] = "Break";
+        Jump[Jump["Continue"] = 4] = "Continue";
+        Jump[Jump["Return"] = 8] = "Return";
+    })(Jump || (Jump = {}));
+    var SuperCaptureResult;
+    (function (SuperCaptureResult) {
+        /**
+         * A capture may have been added for calls to 'super', but
+         * the caller should emit subsequent statements normally.
+         */
+        SuperCaptureResult[SuperCaptureResult["NoReplacement"] = 0] = "NoReplacement";
+        /**
+         * A call to 'super()' got replaced with a capturing statement like:
+         *
+         *  var _this = _super.call(...) || this;
+         *
+         * Callers should skip the current statement.
+         */
+        SuperCaptureResult[SuperCaptureResult["ReplaceSuperCapture"] = 1] = "ReplaceSuperCapture";
+        /**
+         * A call to 'super()' got replaced with a capturing statement like:
+         *
+         *  return _super.call(...) || this;
+         *
+         * Callers should skip the current statement and avoid any returns of '_this'.
+         */
+        SuperCaptureResult[SuperCaptureResult["ReplaceWithReturn"] = 2] = "ReplaceWithReturn";
+    })(SuperCaptureResult || (SuperCaptureResult = {}));
+    // Facts we track as we traverse the tree
+    var HierarchyFacts;
+    (function (HierarchyFacts) {
+        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
+        //
+        // Ancestor facts
+        //
+        HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function";
+        HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction";
+        HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody";
+        HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement";
+        HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis";
+        HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement";
+        HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel";
+        HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block";
+        HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement";
+        HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock";
+        HierarchyFacts[HierarchyFacts["ForStatement"] = 1024] = "ForStatement";
+        HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 2048] = "ForInOrForOfStatement";
+        HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 4096] = "ConstructorWithCapturedSuper";
+        HierarchyFacts[HierarchyFacts["ComputedPropertyName"] = 8192] = "ComputedPropertyName";
+        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
+        //
+        // Ancestor masks
+        //
+        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask";
+        // We are always in *some* kind of block scope, but only specific block-scope containers are
+        // top-level or Blocks.
+        HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes";
+        HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 4032] = "BlockScopeExcludes";
+        // A source file is a top-level block scope.
+        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes";
+        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 3968] = "SourceFileExcludes";
+        // Functions, methods, and accessors are both new lexical scopes and new block scopes.
+        HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes";
+        HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes";
+        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes";
+        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes";
+        // Arrow functions are lexically scoped to their container, but are new block scopes.
+        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes";
+        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 16256] = "ArrowFunctionExcludes";
+        // Constructors are both new lexical scopes and new block scopes. Constructors are also
+        // always considered non-static members of a class.
+        HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes";
+        HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes";
+        // 'do' and 'while' statements are not block scopes. We track that the subtree is contained
+        // within an IterationStatement to indicate whether the embedded statement is an
+        // IterationStatementBlock.
+        HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 256] = "DoOrWhileStatementIncludes";
+        HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes";
+        // 'for' statements are new block scopes and have special handling for 'let' declarations.
+        HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 1280] = "ForStatementIncludes";
+        HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 3008] = "ForStatementExcludes";
+        // 'for-in' and 'for-of' statements are new block scopes and have special handling for
+        // 'let' declarations.
+        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 2304] = "ForInOrForOfStatementIncludes";
+        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 1984] = "ForInOrForOfStatementExcludes";
+        // Blocks (other than function bodies) are new block scopes.
+        HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes";
+        HierarchyFacts[HierarchyFacts["BlockExcludes"] = 3904] = "BlockExcludes";
+        HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes";
+        HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 4032] = "IterationStatementBlockExcludes";
+        // Computed property names track subtree flags differently than their containing members.
+        HierarchyFacts[HierarchyFacts["ComputedPropertyNameIncludes"] = 8192] = "ComputedPropertyNameIncludes";
+        HierarchyFacts[HierarchyFacts["ComputedPropertyNameExcludes"] = 0] = "ComputedPropertyNameExcludes";
+        //
+        // Subtree facts
+        //
+        HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget";
+        HierarchyFacts[HierarchyFacts["NewTargetInComputedPropertyName"] = 32768] = "NewTargetInComputedPropertyName";
+        //
+        // Subtree masks
+        //
+        HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask";
+        HierarchyFacts[HierarchyFacts["PropagateNewTargetMask"] = 49152] = "PropagateNewTargetMask";
+    })(HierarchyFacts || (HierarchyFacts = {}));
+    function transformES2015(context) {
+        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var compilerOptions = context.getCompilerOptions();
+        var resolver = context.getEmitResolver();
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        var previousOnEmitNode = context.onEmitNode;
+        context.onEmitNode = onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        var currentSourceFile;
+        var currentText;
+        var hierarchyFacts;
+        var taggedTemplateStringDeclarations;
+        function recordTaggedTemplateString(temp) {
+            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
+        }
+        /**
+         * Used to track if we are emitting body of the converted loop
+         */
+        var convertedLoopState;
+        /**
+         * Keeps track of whether substitutions have been enabled for specific cases.
+         * They are persisted between each SourceFile transformation and should not
+         * be reset.
+         */
+        var enabledSubstitutions;
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            currentSourceFile = node;
+            currentText = node.text;
+            var visited = visitSourceFile(node);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            currentSourceFile = undefined;
+            currentText = undefined;
+            taggedTemplateStringDeclarations = undefined;
+            hierarchyFacts = 0 /* None */;
+            return visited;
+        }
+        /**
+         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
+         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
+         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
+         */
+        function enterSubtree(excludeFacts, includeFacts) {
+            var ancestorFacts = hierarchyFacts;
+            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */;
+            return ancestorFacts;
+        }
+        /**
+         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
+         * subtree, propagating specific facts from the subtree.
+         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
+         * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
+         * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
+         */
+        function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
+            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts;
+        }
+        function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
+            return hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */
+                && node.kind === 219 /* ReturnStatement */
+                && !node.expression;
+        }
+        function shouldVisitNode(node) {
+            return (node.transformFlags & 128 /* ContainsES2015 */) !== 0
+                || convertedLoopState !== undefined
+                || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */)))
+                || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
+                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
+        }
+        function visitor(node) {
+            if (shouldVisitNode(node)) {
+                return visitJavaScript(node);
+            }
+            else {
+                return node;
+            }
+        }
+        function functionBodyVisitor(node) {
+            if (shouldVisitNode(node)) {
+                return visitBlock(node, /*isFunctionBody*/ true);
+            }
+            return node;
+        }
+        function callExpressionVisitor(node) {
+            if (node.kind === 97 /* SuperKeyword */) {
+                return visitSuperKeyword(/*isExpressionOfCall*/ true);
+            }
+            return visitor(node);
+        }
+        function visitJavaScript(node) {
+            switch (node.kind) {
+                case 115 /* StaticKeyword */:
+                    return undefined; // elide static keyword
+                case 229 /* ClassDeclaration */:
+                    return visitClassDeclaration(node);
+                case 199 /* ClassExpression */:
+                    return visitClassExpression(node);
+                case 146 /* Parameter */:
+                    return visitParameter(node);
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 187 /* ArrowFunction */:
+                    return visitArrowFunction(node);
+                case 186 /* FunctionExpression */:
+                    return visitFunctionExpression(node);
+                case 226 /* VariableDeclaration */:
+                    return visitVariableDeclaration(node);
+                case 71 /* Identifier */:
+                    return visitIdentifier(node);
+                case 227 /* VariableDeclarationList */:
+                    return visitVariableDeclarationList(node);
+                case 221 /* SwitchStatement */:
+                    return visitSwitchStatement(node);
+                case 235 /* CaseBlock */:
+                    return visitCaseBlock(node);
+                case 207 /* Block */:
+                    return visitBlock(node, /*isFunctionBody*/ false);
+                case 218 /* BreakStatement */:
+                case 217 /* ContinueStatement */:
+                    return visitBreakOrContinueStatement(node);
+                case 222 /* LabeledStatement */:
+                    return visitLabeledStatement(node);
+                case 212 /* DoStatement */:
+                case 213 /* WhileStatement */:
+                    return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined);
+                case 214 /* ForStatement */:
+                    return visitForStatement(node, /*outermostLabeledStatement*/ undefined);
+                case 215 /* ForInStatement */:
+                    return visitForInStatement(node, /*outermostLabeledStatement*/ undefined);
+                case 216 /* ForOfStatement */:
+                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
+                case 210 /* ExpressionStatement */:
+                    return visitExpressionStatement(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return visitObjectLiteralExpression(node);
+                case 260 /* CatchClause */:
+                    return visitCatchClause(node);
+                case 262 /* ShorthandPropertyAssignment */:
+                    return visitShorthandPropertyAssignment(node);
+                case 144 /* ComputedPropertyName */:
+                    return visitComputedPropertyName(node);
+                case 177 /* ArrayLiteralExpression */:
+                    return visitArrayLiteralExpression(node);
+                case 181 /* CallExpression */:
+                    return visitCallExpression(node);
+                case 182 /* NewExpression */:
+                    return visitNewExpression(node);
+                case 185 /* ParenthesizedExpression */:
+                    return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true);
+                case 194 /* BinaryExpression */:
+                    return visitBinaryExpression(node, /*needsDestructuringValue*/ true);
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                case 14 /* TemplateHead */:
+                case 15 /* TemplateMiddle */:
+                case 16 /* TemplateTail */:
+                    return visitTemplateLiteral(node);
+                case 9 /* StringLiteral */:
+                    return visitStringLiteral(node);
+                case 8 /* NumericLiteral */:
+                    return visitNumericLiteral(node);
+                case 183 /* TaggedTemplateExpression */:
+                    return visitTaggedTemplateExpression(node);
+                case 196 /* TemplateExpression */:
+                    return visitTemplateExpression(node);
+                case 197 /* YieldExpression */:
+                    return visitYieldExpression(node);
+                case 198 /* SpreadElement */:
+                    return visitSpreadElement(node);
+                case 97 /* SuperKeyword */:
+                    return visitSuperKeyword(/*isExpressionOfCall*/ false);
+                case 99 /* ThisKeyword */:
+                    return visitThisKeyword(node);
+                case 204 /* MetaProperty */:
+                    return visitMetaProperty(node);
+                case 151 /* MethodDeclaration */:
+                    return visitMethodDeclaration(node);
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return visitAccessorDeclaration(node);
+                case 208 /* VariableStatement */:
+                    return visitVariableStatement(node);
+                case 219 /* ReturnStatement */:
+                    return visitReturnStatement(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function visitSourceFile(node) {
+            var ancestorFacts = enterSubtree(3968 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
+            var statements = [];
+            startLexicalEnvironment();
+            var statementOffset = ts.addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false);
+            addCaptureThisForNodeIfNeeded(statements, node);
+            statementOffset = ts.addCustomPrologue(statements, node.statements, statementOffset, visitor);
+            ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
+            if (taggedTemplateStringDeclarations) {
+                statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations)));
+            }
+            ts.addRange(statements, endLexicalEnvironment());
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
+        }
+        function visitSwitchStatement(node) {
+            if (convertedLoopState !== undefined) {
+                var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
+                // for switch statement allow only non-labeled break
+                convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
+                var result = ts.visitEachChild(node, visitor, context);
+                convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
+                return result;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitCaseBlock(node) {
+            var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
+            var updated = ts.visitEachChild(node, visitor, context);
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        function returnCapturedThis(node) {
+            return ts.setOriginalNode(ts.createReturn(ts.createIdentifier("_this")), node);
+        }
+        function visitReturnStatement(node) {
+            if (convertedLoopState) {
+                convertedLoopState.nonLocalJumps |= 8 /* Return */;
+                if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
+                    node = returnCapturedThis(node);
+                }
+                return ts.createReturn(ts.createObjectLiteral([
+                    ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression
+                        ? ts.visitNode(node.expression, visitor, ts.isExpression)
+                        : ts.createVoidZero())
+                ]));
+            }
+            else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
+                return returnCapturedThis(node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitThisKeyword(node) {
+            if (convertedLoopState) {
+                if (hierarchyFacts & 2 /* ArrowFunction */) {
+                    // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword.
+                    convertedLoopState.containsLexicalThis = true;
+                    return node;
+                }
+                return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this"));
+            }
+            return node;
+        }
+        function visitIdentifier(node) {
+            if (!convertedLoopState) {
+                return node;
+            }
+            if (ts.isGeneratedIdentifier(node)) {
+                return node;
+            }
+            if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
+                return node;
+            }
+            return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments"));
+        }
+        function visitBreakOrContinueStatement(node) {
+            if (convertedLoopState) {
+                // check if we can emit break/continue as is
+                // it is possible if either
+                //   - break/continue is labeled and label is located inside the converted loop
+                //   - break/continue is non-labeled and located in non-converted loop/switch statement
+                var jump = node.kind === 218 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
+                var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) ||
+                    (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
+                if (!canUseBreakOrContinue) {
+                    var labelMarker = void 0;
+                    if (!node.label) {
+                        if (node.kind === 218 /* BreakStatement */) {
+                            convertedLoopState.nonLocalJumps |= 2 /* Break */;
+                            labelMarker = "break";
+                        }
+                        else {
+                            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
+                            // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
+                            labelMarker = "continue";
+                        }
+                    }
+                    else {
+                        if (node.kind === 218 /* BreakStatement */) {
+                            labelMarker = "break-" + node.label.escapedText;
+                            setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(node.label), labelMarker);
+                        }
+                        else {
+                            labelMarker = "continue-" + node.label.escapedText;
+                            setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(node.label), labelMarker);
+                        }
+                    }
+                    var returnExpression = ts.createLiteral(labelMarker);
+                    if (convertedLoopState.loopOutParameters.length) {
+                        var outParams = convertedLoopState.loopOutParameters;
+                        var expr = void 0;
+                        for (var i = 0; i < outParams.length; i++) {
+                            var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
+                            if (i === 0) {
+                                expr = copyExpr;
+                            }
+                            else {
+                                expr = ts.createBinary(expr, 26 /* CommaToken */, copyExpr);
+                            }
+                        }
+                        returnExpression = ts.createBinary(expr, 26 /* CommaToken */, returnExpression);
+                    }
+                    return ts.createReturn(returnExpression);
+                }
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a ClassDeclaration and transforms it into a variable statement.
+         *
+         * @param node A ClassDeclaration node.
+         */
+        function visitClassDeclaration(node) {
+            // [source]
+            //      class C { }
+            //
+            // [output]
+            //      var C = (function () {
+            //          function C() {
+            //          }
+            //          return C;
+            //      }());
+            var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), 
+            /*type*/ undefined, transformClassLikeDeclarationToExpression(node));
+            ts.setOriginalNode(variable, node);
+            var statements = [];
+            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable]));
+            ts.setOriginalNode(statement, node);
+            ts.setTextRange(statement, node);
+            ts.startOnNewLine(statement);
+            statements.push(statement);
+            // Add an `export default` statement for default exports (for `--target es5 --module es6`)
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                var exportStatement = ts.hasModifier(node, 512 /* Default */)
+                    ? ts.createExportDefault(ts.getLocalName(node))
+                    : ts.createExternalModuleExport(ts.getLocalName(node));
+                ts.setOriginalNode(exportStatement, statement);
+                statements.push(exportStatement);
+            }
+            var emitFlags = ts.getEmitFlags(node);
+            if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) {
+                // Add a DeclarationMarker as a marker for the end of the declaration
+                statements.push(ts.createEndOfDeclarationMarker(node));
+                ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits a ClassExpression and transforms it into an expression.
+         *
+         * @param node A ClassExpression node.
+         */
+        function visitClassExpression(node) {
+            // [source]
+            //      C = class { }
+            //
+            // [output]
+            //      C = (function () {
+            //          function class_1() {
+            //          }
+            //          return class_1;
+            //      }())
+            return transformClassLikeDeclarationToExpression(node);
+        }
+        /**
+         * Transforms a ClassExpression or ClassDeclaration into an expression.
+         *
+         * @param node A ClassExpression or ClassDeclaration node.
+         */
+        function transformClassLikeDeclarationToExpression(node) {
+            // [source]
+            //      class C extends D {
+            //          constructor() {}
+            //          method() {}
+            //          get prop() {}
+            //          set prop(v) {}
+            //      }
+            //
+            // [output]
+            //      (function (_super) {
+            //          __extends(C, _super);
+            //          function C() {
+            //          }
+            //          C.prototype.method = function () {}
+            //          Object.defineProperty(C.prototype, "prop", {
+            //              get: function() {},
+            //              set: function() {},
+            //              enumerable: true,
+            //              configurable: true
+            //          });
+            //          return C;
+            //      }(D))
+            if (node.name) {
+                enableSubstitutionsForBlockScopedBindings();
+            }
+            var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node);
+            var classFunction = ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [], 
+            /*type*/ undefined, transformClassBody(node, extendsClauseElement));
+            // To preserve the behavior of the old emitter, we explicitly indent
+            // the body of the function here if it was requested in an earlier
+            // transformation.
+            if (ts.getEmitFlags(node) & 65536 /* Indented */) {
+                ts.setEmitFlags(classFunction, 65536 /* Indented */);
+            }
+            // "inner" and "outer" below are added purely to preserve source map locations from
+            // the old emitter
+            var inner = ts.createPartiallyEmittedExpression(classFunction);
+            inner.end = node.end;
+            ts.setEmitFlags(inner, 1536 /* NoComments */);
+            var outer = ts.createPartiallyEmittedExpression(inner);
+            outer.end = ts.skipTrivia(currentText, node.pos);
+            ts.setEmitFlags(outer, 1536 /* NoComments */);
+            var result = ts.createParen(ts.createCall(outer, 
+            /*typeArguments*/ undefined, extendsClauseElement
+                ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)]
+                : []));
+            ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
+            return result;
+        }
+        /**
+         * Transforms a ClassExpression or ClassDeclaration into a function body.
+         *
+         * @param node A ClassExpression or ClassDeclaration node.
+         * @param extendsClauseElement The expression for the class `extends` clause.
+         */
+        function transformClassBody(node, extendsClauseElement) {
+            var statements = [];
+            startLexicalEnvironment();
+            addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
+            addConstructor(statements, node, extendsClauseElement);
+            addClassMembers(statements, node);
+            // Create a synthetic text range for the return statement.
+            var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 18 /* CloseBraceToken */);
+            var localName = ts.getInternalName(node);
+            // The following partially-emitted expression exists purely to align our sourcemap
+            // emit with the original emitter.
+            var outer = ts.createPartiallyEmittedExpression(localName);
+            outer.end = closingBraceLocation.end;
+            ts.setEmitFlags(outer, 1536 /* NoComments */);
+            var statement = ts.createReturn(outer);
+            statement.pos = closingBraceLocation.pos;
+            ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
+            statements.push(statement);
+            ts.addRange(statements, endLexicalEnvironment());
+            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
+            ts.setEmitFlags(block, 1536 /* NoComments */);
+            return block;
+        }
+        /**
+         * Adds a call to the `__extends` helper if needed for a class.
+         *
+         * @param statements The statements of the class body function.
+         * @param node The ClassExpression or ClassDeclaration node.
+         * @param extendsClauseElement The expression for the class `extends` clause.
+         */
+        function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
+            if (extendsClauseElement) {
+                statements.push(ts.setTextRange(ts.createStatement(createExtendsHelper(context, ts.getLocalName(node))), 
+                /*location*/ extendsClauseElement));
+            }
+        }
+        /**
+         * Adds the constructor of the class to a class body function.
+         *
+         * @param statements The statements of the class body function.
+         * @param node The ClassExpression or ClassDeclaration node.
+         * @param extendsClauseElement The expression for the class `extends` clause.
+         */
+        function addConstructor(statements, node, extendsClauseElement) {
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
+            var constructor = ts.getFirstConstructorWithBody(node);
+            var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
+            var constructorFunction = ts.createFunctionDeclaration(
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, ts.getInternalName(node), 
+            /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), 
+            /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper));
+            ts.setTextRange(constructorFunction, constructor || node);
+            if (extendsClauseElement) {
+                ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */);
+            }
+            statements.push(constructorFunction);
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+        }
+        /**
+         * Transforms the parameters of the constructor declaration of a class.
+         *
+         * @param constructor The constructor for the class.
+         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
+         *                            synthesized `super` call.
+         */
+        function transformConstructorParameters(constructor, hasSynthesizedSuper) {
+            // If the TypeScript transformer needed to synthesize a constructor for property
+            // initializers, it would have also added a synthetic `...args` parameter and
+            // `super` call.
+            // If this is the case, we do not include the synthetic `...args` parameter and
+            // will instead use the `arguments` object in ES5/3.
+            return ts.visitParameterList(constructor && !hasSynthesizedSuper && constructor.parameters, visitor, context)
+                || [];
+        }
+        /**
+         * Transforms the body of a constructor declaration of a class.
+         *
+         * @param constructor The constructor for the class.
+         * @param node The node which contains the constructor.
+         * @param extendsClauseElement The expression for the class `extends` clause.
+         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
+         *                            synthesized `super` call.
+         */
+        function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
+            var statements = [];
+            resumeLexicalEnvironment();
+            var statementOffset = -1;
+            if (hasSynthesizedSuper) {
+                // If a super call has already been synthesized,
+                // we're going to assume that we should just transform everything after that.
+                // The assumption is that no prior step in the pipeline has added any prologue directives.
+                statementOffset = 0;
+            }
+            else if (constructor) {
+                statementOffset = ts.addStandardPrologue(statements, constructor.body.statements, /*ensureUseStrict*/ false);
+            }
+            if (constructor) {
+                addDefaultValueAssignmentsIfNeeded(statements, constructor);
+                addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
+                if (!hasSynthesizedSuper) {
+                    // If no super call has been synthesized, emit custom prologue directives.
+                    statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
+                }
+                ts.Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
+            }
+            // determine whether the class is known syntactically to be a derived class (e.g. a
+            // class that extends a value that is not syntactically known to be `null`).
+            var isDerivedClass = extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */;
+            var superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, isDerivedClass, hasSynthesizedSuper, statementOffset);
+            // The last statement expression was replaced. Skip it.
+            if (superCaptureStatus === 1 /* ReplaceSuperCapture */ || superCaptureStatus === 2 /* ReplaceWithReturn */) {
+                statementOffset++;
+            }
+            if (constructor) {
+                if (superCaptureStatus === 1 /* ReplaceSuperCapture */) {
+                    hierarchyFacts |= 4096 /* ConstructorWithCapturedSuper */;
+                }
+                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset));
+            }
+            // Return `_this` unless we're sure enough that it would be pointless to add a return statement.
+            // If there's a constructor that we can tell returns in enough places, then we *do not* want to add a return.
+            if (isDerivedClass
+                && superCaptureStatus !== 2 /* ReplaceWithReturn */
+                && !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) {
+                statements.push(ts.createReturn(ts.createIdentifier("_this")));
+            }
+            ts.addRange(statements, endLexicalEnvironment());
+            if (constructor) {
+                prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false);
+            }
+            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
+            /*location*/ constructor ? constructor.body.statements : node.members), 
+            /*multiLine*/ true);
+            ts.setTextRange(block, constructor ? constructor.body : node);
+            if (!constructor) {
+                ts.setEmitFlags(block, 1536 /* NoComments */);
+            }
+            return block;
+        }
+        /**
+         * We want to try to avoid emitting a return statement in certain cases if a user already returned something.
+         * It would generate obviously dead code, so we'll try to make things a little bit prettier
+         * by doing a minimal check on whether some common patterns always explicitly return.
+         */
+        function isSufficientlyCoveredByReturnStatements(statement) {
+            // A return statement is considered covered.
+            if (statement.kind === 219 /* ReturnStatement */) {
+                return true;
+            }
+            else if (statement.kind === 211 /* IfStatement */) {
+                var ifStatement = statement;
+                if (ifStatement.elseStatement) {
+                    return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) &&
+                        isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
+                }
+            }
+            else if (statement.kind === 207 /* Block */) {
+                var lastStatement = ts.lastOrUndefined(statement.statements);
+                if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        /**
+         * Declares a `_this` variable for derived classes and for when arrow functions capture `this`.
+         *
+         * @returns The new statement offset into the `statements` array.
+         */
+        function declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, ctor, isDerivedClass, hasSynthesizedSuper, statementOffset) {
+            // If this isn't a derived class, just capture 'this' for arrow functions if necessary.
+            if (!isDerivedClass) {
+                if (ctor) {
+                    addCaptureThisForNodeIfNeeded(statements, ctor);
+                }
+                return 0 /* NoReplacement */;
+            }
+            // We must be here because the user didn't write a constructor
+            // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
+            // If that's the case we can just immediately return the result of a 'super()' call.
+            if (!ctor) {
+                statements.push(ts.createReturn(createDefaultSuperCallOrThis()));
+                return 2 /* ReplaceWithReturn */;
+            }
+            // The constructor exists, but it and the 'super()' call it contains were generated
+            // for something like property initializers.
+            // Create a captured '_this' variable and assume it will subsequently be used.
+            if (hasSynthesizedSuper) {
+                captureThisForNode(statements, ctor, createDefaultSuperCallOrThis());
+                enableSubstitutionsForCapturedThis();
+                return 1 /* ReplaceSuperCapture */;
+            }
+            // Most of the time, a 'super' call will be the first real statement in a constructor body.
+            // In these cases, we'd like to transform these into a *single* statement instead of a declaration
+            // followed by an assignment statement for '_this'. For instance, if we emitted without an initializer,
+            // we'd get:
+            //
+            //      var _this;
+            //      _this = _super.call(...) || this;
+            //
+            // instead of
+            //
+            //      var _this = _super.call(...) || this;
+            //
+            // Additionally, if the 'super()' call is the last statement, we should just avoid capturing
+            // entirely and immediately return the result like so:
+            //
+            //      return _super.call(...) || this;
+            //
+            var firstStatement;
+            var superCallExpression;
+            var ctorStatements = ctor.body.statements;
+            if (statementOffset < ctorStatements.length) {
+                firstStatement = ctorStatements[statementOffset];
+                if (firstStatement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(firstStatement.expression)) {
+                    superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression);
+                }
+            }
+            // Return the result if we have an immediate super() call on the last statement,
+            // but only if the constructor itself doesn't use 'this' elsewhere.
+            if (superCallExpression
+                && statementOffset === ctorStatements.length - 1
+                && !(ctor.transformFlags & (16384 /* ContainsLexicalThis */ | 32768 /* ContainsCapturedLexicalThis */))) {
+                var returnStatement = ts.createReturn(superCallExpression);
+                if (superCallExpression.kind !== 194 /* BinaryExpression */
+                    || superCallExpression.left.kind !== 181 /* CallExpression */) {
+                    ts.Debug.fail("Assumed generated super call would have form 'super.call(...) || this'.");
+                }
+                // Shift comments from the original super call to the return statement.
+                ts.setCommentRange(returnStatement, ts.getCommentRange(ts.setEmitFlags(superCallExpression.left, 1536 /* NoComments */)));
+                statements.push(returnStatement);
+                return 2 /* ReplaceWithReturn */;
+            }
+            // Perform the capture.
+            captureThisForNode(statements, ctor, superCallExpression || createActualThis(), firstStatement);
+            // If we're actually replacing the original statement, we need to signal this to the caller.
+            if (superCallExpression) {
+                return 1 /* ReplaceSuperCapture */;
+            }
+            return 0 /* NoReplacement */;
+        }
+        function createActualThis() {
+            return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */);
+        }
+        function createDefaultSuperCallOrThis() {
+            return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createIdentifier("_super"), ts.createNull()), ts.createFunctionApply(ts.createIdentifier("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis());
+        }
+        /**
+         * Visits a parameter declaration.
+         *
+         * @param node A ParameterDeclaration node.
+         */
+        function visitParameter(node) {
+            if (node.dotDotDotToken) {
+                // rest parameters are elided
+                return undefined;
+            }
+            else if (ts.isBindingPattern(node.name)) {
+                // Binding patterns are converted into a generated name and are
+                // evaluated inside the function body.
+                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, 
+                /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), 
+                /*questionToken*/ undefined, 
+                /*type*/ undefined, 
+                /*initializer*/ undefined), 
+                /*location*/ node), 
+                /*original*/ node);
+            }
+            else if (node.initializer) {
+                // Initializers are elided
+                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, 
+                /*dotDotDotToken*/ undefined, node.name, 
+                /*questionToken*/ undefined, 
+                /*type*/ undefined, 
+                /*initializer*/ undefined), 
+                /*location*/ node), 
+                /*original*/ node);
+            }
+            else {
+                return node;
+            }
+        }
+        /**
+         * Gets a value indicating whether we need to add default value assignments for a
+         * function-like node.
+         *
+         * @param node A function-like node.
+         */
+        function shouldAddDefaultValueAssignments(node) {
+            return (node.transformFlags & 131072 /* ContainsDefaultValueAssignments */) !== 0;
+        }
+        /**
+         * Adds statements to the body of a function-like node if it contains parameters with
+         * binding patterns or initializers.
+         *
+         * @param statements The statements for the new function body.
+         * @param node A function-like node.
+         */
+        function addDefaultValueAssignmentsIfNeeded(statements, node) {
+            if (!shouldAddDefaultValueAssignments(node)) {
+                return;
+            }
+            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
+                var parameter = _a[_i];
+                var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken;
+                // A rest parameter cannot have a binding pattern or an initializer,
+                // so let's just ignore it.
+                if (dotDotDotToken) {
+                    continue;
+                }
+                if (ts.isBindingPattern(name)) {
+                    addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer);
+                }
+                else if (initializer) {
+                    addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
+                }
+            }
+        }
+        /**
+         * Adds statements to the body of a function-like node for parameters with binding patterns
+         *
+         * @param statements The statements for the new function body.
+         * @param parameter The parameter for the function.
+         * @param name The name of the parameter.
+         * @param initializer The initializer for the parameter.
+         */
+        function addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
+            var temp = ts.getGeneratedNameForNode(parameter);
+            // In cases where a binding pattern is simply '[]' or '{}',
+            // we usually don't want to emit a var declaration; however, in the presence
+            // of an initializer, we must emit that expression to preserve side effects.
+            if (name.elements.length > 0) {
+                statements.push(ts.setEmitFlags(ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, temp))), 1048576 /* CustomPrologue */));
+            }
+            else if (initializer) {
+                statements.push(ts.setEmitFlags(ts.createStatement(ts.createAssignment(temp, ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */));
+            }
+        }
+        /**
+         * Adds statements to the body of a function-like node for parameters with initializers.
+         *
+         * @param statements The statements for the new function body.
+         * @param parameter The parameter for the function.
+         * @param name The name of the parameter.
+         * @param initializer The initializer for the parameter.
+         */
+        function addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
+            initializer = ts.visitNode(initializer, visitor, ts.isExpression);
+            var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
+                ts.createStatement(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer))), parameter))
+            ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */));
+            statement.startsOnNewLine = true;
+            ts.setTextRange(statement, parameter);
+            ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */);
+            statements.push(statement);
+        }
+        /**
+         * Gets a value indicating whether we need to add statements to handle a rest parameter.
+         *
+         * @param node A ParameterDeclaration node.
+         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
+         *                                          part of a constructor declaration with a
+         *                                          synthesized call to `super`
+         */
+        function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
+            return node && node.dotDotDotToken && node.name.kind === 71 /* Identifier */ && !inConstructorWithSynthesizedSuper;
+        }
+        /**
+         * Adds statements to the body of a function-like node if it contains a rest parameter.
+         *
+         * @param statements The statements for the new function body.
+         * @param node A function-like node.
+         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
+         *                                          part of a constructor declaration with a
+         *                                          synthesized call to `super`
+         */
+        function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
+            var parameter = ts.lastOrUndefined(node.parameters);
+            if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
+                return;
+            }
+            // `declarationName` is the name of the local declaration for the parameter.
+            var declarationName = ts.getMutableClone(parameter.name);
+            ts.setEmitFlags(declarationName, 48 /* NoSourceMap */);
+            // `expressionName` is the name of the parameter used in expressions.
+            var expressionName = ts.getSynthesizedClone(parameter.name);
+            var restIndex = node.parameters.length - 1;
+            var temp = ts.createLoopVariable();
+            // var param = [];
+            statements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(declarationName, 
+                /*type*/ undefined, ts.createArrayLiteral([]))
+            ])), 
+            /*location*/ parameter), 1048576 /* CustomPrologue */));
+            // for (var _i = restIndex; _i < arguments.length; _i++) {
+            //   param[_i - restIndex] = arguments[_i];
+            // }
+            var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex))
+            ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([
+                ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0
+                    ? temp
+                    : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), 
+                /*location*/ parameter))
+            ]));
+            ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */);
+            ts.startOnNewLine(forStatement);
+            statements.push(forStatement);
+        }
+        /**
+         * Adds a statement to capture the `this` of a function declaration if it is needed.
+         *
+         * @param statements The statements for the new function body.
+         * @param node A node.
+         */
+        function addCaptureThisForNodeIfNeeded(statements, node) {
+            if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */ && node.kind !== 187 /* ArrowFunction */) {
+                captureThisForNode(statements, node, ts.createThis());
+            }
+        }
+        function captureThisForNode(statements, node, initializer, originalStatement) {
+            enableSubstitutionsForCapturedThis();
+            var captureThisStatement = ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                ts.createVariableDeclaration("_this", 
+                /*type*/ undefined, initializer)
+            ]));
+            ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
+            ts.setTextRange(captureThisStatement, originalStatement);
+            ts.setSourceMapRange(captureThisStatement, node);
+            statements.push(captureThisStatement);
+        }
+        function prependCaptureNewTargetIfNeeded(statements, node, copyOnWrite) {
+            if (hierarchyFacts & 16384 /* NewTarget */) {
+                var newTarget = void 0;
+                switch (node.kind) {
+                    case 187 /* ArrowFunction */:
+                        return statements;
+                    case 151 /* MethodDeclaration */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        // Methods and accessors cannot be constructors, so 'new.target' will
+                        // always return 'undefined'.
+                        newTarget = ts.createVoidZero();
+                        break;
+                    case 152 /* Constructor */:
+                        // Class constructors can only be called with `new`, so `this.constructor`
+                        // should be relatively safe to use.
+                        newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor");
+                        break;
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                        // Functions can be called or constructed, and may have a `this` due to
+                        // being a member or when calling an imported function via `other_1.f()`.
+                        newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 93 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero());
+                        break;
+                    default:
+                        ts.Debug.failBadSyntaxKind(node);
+                        break;
+                }
+                var captureNewTargetStatement = ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                    ts.createVariableDeclaration("_newTarget", 
+                    /*type*/ undefined, newTarget)
+                ]));
+                if (copyOnWrite) {
+                    return [captureNewTargetStatement].concat(statements);
+                }
+                statements.unshift(captureNewTargetStatement);
+            }
+            return statements;
+        }
+        /**
+         * Adds statements to the class body function for a class to define the members of the
+         * class.
+         *
+         * @param statements The statements for the class body function.
+         * @param node The ClassExpression or ClassDeclaration node.
+         */
+        function addClassMembers(statements, node) {
+            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
+                var member = _a[_i];
+                switch (member.kind) {
+                    case 206 /* SemicolonClassElement */:
+                        statements.push(transformSemicolonClassElementToStatement(member));
+                        break;
+                    case 151 /* MethodDeclaration */:
+                        statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
+                        break;
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
+                        if (member === accessors.firstAccessor) {
+                            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
+                        }
+                        break;
+                    case 152 /* Constructor */:
+                        // Constructors are handled in visitClassExpression/visitClassDeclaration
+                        break;
+                    default:
+                        ts.Debug.failBadSyntaxKind(node);
+                        break;
+                }
+            }
+        }
+        /**
+         * Transforms a SemicolonClassElement into a statement for a class body function.
+         *
+         * @param member The SemicolonClassElement node.
+         */
+        function transformSemicolonClassElementToStatement(member) {
+            return ts.setTextRange(ts.createEmptyStatement(), member);
+        }
+        /**
+         * Transforms a MethodDeclaration into a statement for a class body function.
+         *
+         * @param receiver The receiver for the member.
+         * @param member The MethodDeclaration node.
+         */
+        function transformClassMethodDeclarationToStatement(receiver, member, container) {
+            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
+            var commentRange = ts.getCommentRange(member);
+            var sourceMapRange = ts.getSourceMapRange(member);
+            var memberName = ts.createMemberAccessForPropertyName(receiver, ts.visitNode(member.name, visitor, ts.isPropertyName), /*location*/ member.name);
+            var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
+            ts.setEmitFlags(memberFunction, 1536 /* NoComments */);
+            ts.setSourceMapRange(memberFunction, sourceMapRange);
+            var statement = ts.setTextRange(ts.createStatement(ts.createAssignment(memberName, memberFunction)), 
+            /*location*/ member);
+            ts.setOriginalNode(statement, member);
+            ts.setCommentRange(statement, commentRange);
+            // The location for the statement is used to emit comments only.
+            // No source map should be emitted for this statement to align with the
+            // old emitter.
+            ts.setEmitFlags(statement, 48 /* NoSourceMap */);
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
+            return statement;
+        }
+        /**
+         * Transforms a set of related of get/set accessors into a statement for a class body function.
+         *
+         * @param receiver The receiver for the member.
+         * @param accessors The set of related get/set accessors.
+         */
+        function transformAccessorsToStatement(receiver, accessors, container) {
+            var statement = ts.createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
+            // The location for the statement is used to emit source maps only.
+            // No comments should be emitted for this statement to align with the
+            // old emitter.
+            ts.setEmitFlags(statement, 1536 /* NoComments */);
+            ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor));
+            return statement;
+        }
+        /**
+         * Transforms a set of related get/set accessors into an expression for either a class
+         * body function or an ObjectLiteralExpression with computed properties.
+         *
+         * @param receiver The receiver for the member.
+         */
+        function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) {
+            var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
+            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
+            // To align with source maps in the old emitter, the receiver and property name
+            // arguments are both mapped contiguously to the accessor name.
+            var target = ts.getMutableClone(receiver);
+            ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */);
+            ts.setSourceMapRange(target, firstAccessor.name);
+            var propertyName = ts.createExpressionForPropertyName(ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName));
+            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */);
+            ts.setSourceMapRange(propertyName, firstAccessor.name);
+            var properties = [];
+            if (getAccessor) {
+                var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container);
+                ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor));
+                ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */);
+                var getter = ts.createPropertyAssignment("get", getterFunction);
+                ts.setCommentRange(getter, ts.getCommentRange(getAccessor));
+                properties.push(getter);
+            }
+            if (setAccessor) {
+                var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container);
+                ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor));
+                ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */);
+                var setter = ts.createPropertyAssignment("set", setterFunction);
+                ts.setCommentRange(setter, ts.getCommentRange(setAccessor));
+                properties.push(setter);
+            }
+            properties.push(ts.createPropertyAssignment("enumerable", ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue()));
+            var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
+            /*typeArguments*/ undefined, [
+                target,
+                propertyName,
+                ts.createObjectLiteral(properties, /*multiLine*/ true)
+            ]);
+            if (startsOnNewLine) {
+                call.startsOnNewLine = true;
+            }
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
+            return call;
+        }
+        /**
+         * Visits an ArrowFunction and transforms it into a FunctionExpression.
+         *
+         * @param node An ArrowFunction node.
+         */
+        function visitArrowFunction(node) {
+            if (node.transformFlags & 16384 /* ContainsLexicalThis */) {
+                enableSubstitutionsForCapturedThis();
+            }
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var ancestorFacts = enterSubtree(16256 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
+            var func = ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+            /*type*/ undefined, transformFunctionBody(node));
+            ts.setTextRange(func, node);
+            ts.setOriginalNode(func, node);
+            ts.setEmitFlags(func, 8 /* CapturesThis */);
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+            return func;
+        }
+        /**
+         * Visits a FunctionExpression node.
+         *
+         * @param node a FunctionExpression node.
+         */
+        function visitFunctionExpression(node) {
+            var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */
+                ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */)
+                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var parameters = ts.visitParameterList(node.parameters, visitor, context);
+            var body = node.transformFlags & 64 /* ES2015 */
+                ? transformFunctionBody(node)
+                : visitFunctionBodyDownLevel(node);
+            var name = hierarchyFacts & 16384 /* NewTarget */
+                ? ts.getLocalName(node)
+                : node.name;
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+            return ts.updateFunctionExpression(node, 
+            /*modifiers*/ undefined, node.asteriskToken, name, 
+            /*typeParameters*/ undefined, parameters, 
+            /*type*/ undefined, body);
+        }
+        /**
+         * Visits a FunctionDeclaration node.
+         *
+         * @param node a FunctionDeclaration node.
+         */
+        function visitFunctionDeclaration(node) {
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
+            var parameters = ts.visitParameterList(node.parameters, visitor, context);
+            var body = node.transformFlags & 64 /* ES2015 */
+                ? transformFunctionBody(node)
+                : visitFunctionBodyDownLevel(node);
+            var name = hierarchyFacts & 16384 /* NewTarget */
+                ? ts.getLocalName(node)
+                : node.name;
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+            return ts.updateFunctionDeclaration(node, 
+            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, 
+            /*typeParameters*/ undefined, parameters, 
+            /*type*/ undefined, body);
+        }
+        /**
+         * Transforms a function-like node into a FunctionExpression.
+         *
+         * @param node The function-like node to transform.
+         * @param location The source-map location for the new FunctionExpression.
+         * @param name The name of the new FunctionExpression.
+         */
+        function transformFunctionLikeToExpression(node, location, name, container) {
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */)
+                ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */)
+                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
+            var parameters = ts.visitParameterList(node.parameters, visitor, context);
+            var body = transformFunctionBody(node);
+            if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 228 /* FunctionDeclaration */ || node.kind === 186 /* FunctionExpression */)) {
+                name = ts.getGeneratedNameForNode(node);
+            }
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+            return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
+            /*modifiers*/ undefined, node.asteriskToken, name, 
+            /*typeParameters*/ undefined, parameters, 
+            /*type*/ undefined, body), location), 
+            /*original*/ node);
+        }
+        /**
+         * Transforms the body of a function-like node.
+         *
+         * @param node A function-like node.
+         */
+        function transformFunctionBody(node) {
+            var multiLine = false; // indicates whether the block *must* be emitted as multiple lines
+            var singleLine = false; // indicates whether the block *may* be emitted as a single line
+            var statementsLocation;
+            var closeBraceLocation;
+            var statements = [];
+            var body = node.body;
+            var statementOffset;
+            resumeLexicalEnvironment();
+            if (ts.isBlock(body)) {
+                // ensureUseStrict is false because no new prologue-directive should be added.
+                // addStandardPrologue will put already-existing directives at the beginning of the target statement-array
+                statementOffset = ts.addStandardPrologue(statements, body.statements, /*ensureUseStrict*/ false);
+            }
+            addCaptureThisForNodeIfNeeded(statements, node);
+            addDefaultValueAssignmentsIfNeeded(statements, node);
+            addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
+            // If we added any generated statements, this must be a multi-line block.
+            if (!multiLine && statements.length > 0) {
+                multiLine = true;
+            }
+            if (ts.isBlock(body)) {
+                // addCustomPrologue puts already-existing directives at the beginning of the target statement-array
+                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor);
+                statementsLocation = body.statements;
+                ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset));
+                // If the original body was a multi-line block, this must be a multi-line block.
+                if (!multiLine && body.multiLine) {
+                    multiLine = true;
+                }
+            }
+            else {
+                ts.Debug.assert(node.kind === 187 /* ArrowFunction */);
+                // To align with the old emitter, we use a synthetic end position on the location
+                // for the statement list we synthesize when we down-level an arrow function with
+                // an expression function body. This prevents both comments and source maps from
+                // being emitted for the end position only.
+                statementsLocation = ts.moveRangeEnd(body, -1);
+                var equalsGreaterThanToken = node.equalsGreaterThanToken;
+                if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) {
+                    if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
+                        singleLine = true;
+                    }
+                    else {
+                        multiLine = true;
+                    }
+                }
+                var expression = ts.visitNode(body, visitor, ts.isExpression);
+                var returnStatement = ts.createReturn(expression);
+                ts.setTextRange(returnStatement, body);
+                ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */);
+                statements.push(returnStatement);
+                // To align with the source map emit for the old emitter, we set a custom
+                // source map location for the close brace.
+                closeBraceLocation = body;
+            }
+            var lexicalEnvironment = context.endLexicalEnvironment();
+            ts.addRange(statements, lexicalEnvironment);
+            prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
+            // If we added any final generated statements, this must be a multi-line block
+            if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) {
+                multiLine = true;
+            }
+            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine);
+            ts.setTextRange(block, node.body);
+            if (!multiLine && singleLine) {
+                ts.setEmitFlags(block, 1 /* SingleLine */);
+            }
+            if (closeBraceLocation) {
+                ts.setTokenSourceMapRange(block, 18 /* CloseBraceToken */, closeBraceLocation);
+            }
+            ts.setOriginalNode(block, node.body);
+            return block;
+        }
+        function visitFunctionBodyDownLevel(node) {
+            var updated = ts.visitFunctionBody(node.body, functionBodyVisitor, context);
+            return ts.updateBlock(updated, ts.setTextRange(ts.createNodeArray(prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)), 
+            /*location*/ updated.statements));
+        }
+        function visitBlock(node, isFunctionBody) {
+            if (isFunctionBody) {
+                // A function body is not a block scope.
+                return ts.visitEachChild(node, visitor, context);
+            }
+            var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */
+                ? enterSubtree(4032 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */)
+                : enterSubtree(3904 /* BlockExcludes */, 128 /* BlockIncludes */);
+            var updated = ts.visitEachChild(node, visitor, context);
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        /**
+         * Visits an ExpressionStatement that contains a destructuring assignment.
+         *
+         * @param node An ExpressionStatement node.
+         */
+        function visitExpressionStatement(node) {
+            // If we are here it is most likely because our expression is a destructuring assignment.
+            switch (node.expression.kind) {
+                case 185 /* ParenthesizedExpression */:
+                    return ts.updateStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
+                case 194 /* BinaryExpression */:
+                    return ts.updateStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a ParenthesizedExpression that may contain a destructuring assignment.
+         *
+         * @param node A ParenthesizedExpression node.
+         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
+         *                                of a destructuring assignment.
+         */
+        function visitParenthesizedExpression(node, needsDestructuringValue) {
+            // If we are here it is most likely because our expression is a destructuring assignment.
+            if (!needsDestructuringValue) {
+                // By default we always emit the RHS at the end of a flattened destructuring
+                // expression. If we are in a state where we do not need the destructuring value,
+                // we pass that information along to the children that care about it.
+                switch (node.expression.kind) {
+                    case 185 /* ParenthesizedExpression */:
+                        return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
+                    case 194 /* BinaryExpression */:
+                        return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
+                }
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a BinaryExpression that contains a destructuring assignment.
+         *
+         * @param node A BinaryExpression node.
+         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
+         *                                of a destructuring assignment.
+         */
+        function visitBinaryExpression(node, needsDestructuringValue) {
+            // If we are here it is because this is a destructuring assignment.
+            if (ts.isDestructuringAssignment(node)) {
+                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitVariableStatement(node) {
+            var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
+            var updated;
+            if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0) {
+                // we are inside a converted loop - hoist variable declarations
+                var assignments = void 0;
+                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
+                    if (decl.initializer) {
+                        var assignment = void 0;
+                        if (ts.isBindingPattern(decl.name)) {
+                            assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */);
+                        }
+                        else {
+                            assignment = ts.createBinary(decl.name, 58 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression));
+                            ts.setTextRange(assignment, decl);
+                        }
+                        assignments = ts.append(assignments, assignment);
+                    }
+                }
+                if (assignments) {
+                    updated = ts.setTextRange(ts.createStatement(ts.inlineExpressions(assignments)), node);
+                }
+                else {
+                    // none of declarations has initializer - the entire variable statement can be deleted
+                    updated = undefined;
+                }
+            }
+            else {
+                updated = ts.visitEachChild(node, visitor, context);
+            }
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        /**
+         * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
+         *
+         * @param node A VariableDeclarationList node.
+         */
+        function visitVariableDeclarationList(node) {
+            if (node.transformFlags & 64 /* ES2015 */) {
+                if (node.flags & 3 /* BlockScoped */) {
+                    enableSubstitutionsForBlockScopedBindings();
+                }
+                var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */
+                    ? visitVariableDeclarationInLetDeclarationList
+                    : visitVariableDeclaration);
+                var declarationList = ts.createVariableDeclarationList(declarations);
+                ts.setOriginalNode(declarationList, node);
+                ts.setTextRange(declarationList, node);
+                ts.setCommentRange(declarationList, node);
+                if (node.transformFlags & 8388608 /* ContainsBindingPattern */
+                    && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) {
+                    // If the first or last declaration is a binding pattern, we need to modify
+                    // the source map range for the declaration list.
+                    var firstDeclaration = ts.firstOrUndefined(declarations);
+                    if (firstDeclaration) {
+                        var lastDeclaration = ts.lastOrUndefined(declarations);
+                        ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end));
+                    }
+                }
+                return declarationList;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Gets a value indicating whether we should emit an explicit initializer for a variable
+         * declaration in a `let` declaration list.
+         *
+         * @param node A VariableDeclaration node.
+         */
+        function shouldEmitExplicitInitializerForLetDeclaration(node) {
+            // Nested let bindings might need to be initialized explicitly to preserve
+            // ES6 semantic:
+            //
+            //  { let x = 1; }
+            //  { let x; } // x here should be undefined. not 1
+            //
+            // Top level bindings never collide with anything and thus don't require
+            // explicit initialization. As for nested let bindings there are two cases:
+            //
+            // - Nested let bindings that were not renamed definitely should be
+            //   initialized explicitly:
+            //
+            //    { let x = 1; }
+            //    { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } }
+            //
+            //   Without explicit initialization code in /*1*/ can be executed even if
+            //   some-condition is evaluated to false.
+            //
+            // - Renaming introduces fresh name that should not collide with any
+            //   existing names, however renamed bindings sometimes also should be
+            //   explicitly initialized. One particular case: non-captured binding
+            //   declared inside loop body (but not in loop initializer):
+            //
+            //    let x;
+            //    for (;;) {
+            //        let x;
+            //    }
+            //
+            //   In downlevel codegen inner 'x' will be renamed so it won't collide
+            //   with outer 'x' however it will should be reset on every iteration as
+            //   if it was declared anew.
+            //
+            //   * Why non-captured binding?
+            //     - Because if loop contains block scoped binding captured in some
+            //       function then loop body will be rewritten to have a fresh scope
+            //       on every iteration so everything will just work.
+            //
+            //   * Why loop initializer is excluded?
+            //     - Since we've introduced a fresh name it already will be undefined.
+            var flags = resolver.getNodeCheckFlags(node);
+            var isCapturedInFunction = flags & 131072 /* CapturedBlockScopedBinding */;
+            var isDeclaredInLoop = flags & 262144 /* BlockScopedBindingInLoop */;
+            var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0
+                || (isCapturedInFunction
+                    && isDeclaredInLoop
+                    && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0);
+            var emitExplicitInitializer = !emittedAsTopLevel
+                && (hierarchyFacts & 2048 /* ForInOrForOfStatement */) === 0
+                && (!resolver.isDeclarationWithCollidingName(node)
+                    || (isDeclaredInLoop
+                        && !isCapturedInFunction
+                        && (hierarchyFacts & (1024 /* ForStatement */ | 2048 /* ForInOrForOfStatement */)) === 0));
+            return emitExplicitInitializer;
+        }
+        /**
+         * Visits a VariableDeclaration in a `let` declaration list.
+         *
+         * @param node A VariableDeclaration node.
+         */
+        function visitVariableDeclarationInLetDeclarationList(node) {
+            // For binding pattern names that lack initializers there is no point to emit
+            // explicit initializer since downlevel codegen for destructuring will fail
+            // in the absence of initializer so all binding elements will say uninitialized
+            var name = node.name;
+            if (ts.isBindingPattern(name)) {
+                return visitVariableDeclaration(node);
+            }
+            if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
+                var clone_2 = ts.getMutableClone(node);
+                clone_2.initializer = ts.createVoidZero();
+                return clone_2;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a VariableDeclaration node with a binding pattern.
+         *
+         * @param node A VariableDeclaration node.
+         */
+        function visitVariableDeclaration(node) {
+            var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
+            var updated;
+            if (ts.isBindingPattern(node.name)) {
+                updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, 
+                /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0);
+            }
+            else {
+                updated = ts.visitEachChild(node, visitor, context);
+            }
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        function recordLabel(node) {
+            convertedLoopState.labels.set(ts.idText(node.label), true);
+        }
+        function resetLabel(node) {
+            convertedLoopState.labels.set(ts.idText(node.label), false);
+        }
+        function visitLabeledStatement(node) {
+            if (convertedLoopState && !convertedLoopState.labels) {
+                convertedLoopState.labels = ts.createMap();
+            }
+            var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
+            return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false)
+                ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
+                : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement), node, convertedLoopState && resetLabel);
+        }
+        function visitIterationStatement(node, outermostLabeledStatement) {
+            switch (node.kind) {
+                case 212 /* DoStatement */:
+                case 213 /* WhileStatement */:
+                    return visitDoOrWhileStatement(node, outermostLabeledStatement);
+                case 214 /* ForStatement */:
+                    return visitForStatement(node, outermostLabeledStatement);
+                case 215 /* ForInStatement */:
+                    return visitForInStatement(node, outermostLabeledStatement);
+                case 216 /* ForOfStatement */:
+                    return visitForOfStatement(node, outermostLabeledStatement);
+            }
+        }
+        function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
+            var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
+            var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        function visitDoOrWhileStatement(node, outermostLabeledStatement) {
+            return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 256 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement);
+        }
+        function visitForStatement(node, outermostLabeledStatement) {
+            return visitIterationStatementWithFacts(3008 /* ForStatementExcludes */, 1280 /* ForStatementIncludes */, node, outermostLabeledStatement);
+        }
+        function visitForInStatement(node, outermostLabeledStatement) {
+            return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement);
+        }
+        function visitForOfStatement(node, outermostLabeledStatement) {
+            return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
+        }
+        function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
+            var statements = [];
+            if (ts.isVariableDeclarationList(node.initializer)) {
+                if (node.initializer.flags & 3 /* BlockScoped */) {
+                    enableSubstitutionsForBlockScopedBindings();
+                }
+                var firstOriginalDeclaration = ts.firstOrUndefined(node.initializer.declarations);
+                if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) {
+                    // This works whether the declaration is a var, let, or const.
+                    // It will use rhsIterationValue _a[_i] as the initializer.
+                    var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue);
+                    var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer);
+                    ts.setOriginalNode(declarationList, node.initializer);
+                    // Adjust the source map range for the first declaration to align with the old
+                    // emitter.
+                    var firstDeclaration = declarations[0];
+                    var lastDeclaration = ts.lastOrUndefined(declarations);
+                    ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end));
+                    statements.push(ts.createVariableStatement(
+                    /*modifiers*/ undefined, declarationList));
+                }
+                else {
+                    // The following call does not include the initializer, so we have
+                    // to emit it separately.
+                    statements.push(ts.setTextRange(ts.createVariableStatement(
+                    /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([
+                        ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), 
+                        /*type*/ undefined, boundValue)
+                    ]), ts.moveRangePos(node.initializer, -1)), node.initializer)), ts.moveRangeEnd(node.initializer, -1)));
+                }
+            }
+            else {
+                // Initializer is an expression. Emit the expression in the body, so that it's
+                // evaluated on every iteration.
+                var assignment = ts.createAssignment(node.initializer, boundValue);
+                if (ts.isDestructuringAssignment(assignment)) {
+                    ts.aggregateTransformFlags(assignment);
+                    statements.push(ts.createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
+                }
+                else {
+                    assignment.end = node.initializer.end;
+                    statements.push(ts.setTextRange(ts.createStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(node.initializer, -1)));
+                }
+            }
+            var bodyLocation;
+            var statementsLocation;
+            if (convertedLoopBodyStatements) {
+                ts.addRange(statements, convertedLoopBodyStatements);
+            }
+            else {
+                var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
+                if (ts.isBlock(statement)) {
+                    ts.addRange(statements, statement.statements);
+                    bodyLocation = statement;
+                    statementsLocation = statement.statements;
+                }
+                else {
+                    statements.push(statement);
+                }
+            }
+            // The old emitter does not emit source maps for the block.
+            // We add the location to preserve comments.
+            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
+            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
+        }
+        function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
+            // The following ES6 code:
+            //
+            //    for (let v of expr) { }
+            //
+            // should be emitted as
+            //
+            //    for (var _i = 0, _a = expr; _i < _a.length; _i++) {
+            //        var v = _a[_i];
+            //    }
+            //
+            // where _a and _i are temps emitted to capture the RHS and the counter,
+            // respectively.
+            // When the left hand side is an expression instead of a let declaration,
+            // the "let v" is not emitted.
+            // When the left hand side is a let/const, the v is renamed if there is
+            // another v in scope.
+            // Note that all assignments to the LHS are emitted in the body, including
+            // all destructuring.
+            // Note also that because an extra statement is needed to assign to the LHS,
+            // for-of bodies are always emitted as blocks.
+            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+            // In the case where the user wrote an identifier as the RHS, like this:
+            //
+            //     for (let v of arr) { }
+            //
+            // we don't want to emit a temporary variable for the RHS, just use it directly.
+            var counter = ts.createLoopVariable();
+            var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            // The old emitter does not emit source maps for the expression
+            ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression));
+            var forStatement = ts.setTextRange(ts.createFor(
+            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
+                ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)),
+                ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
+            ]), node.expression), 2097152 /* NoHoisting */), 
+            /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), 
+            /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), 
+            /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), 
+            /*location*/ node);
+            // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
+            ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */);
+            ts.setTextRange(forStatement, node);
+            return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
+        }
+        function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements) {
+            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var errorRecord = ts.createUniqueName("e");
+            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
+            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
+            var values = ts.createValuesHelper(context, expression, node.expression);
+            var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
+            hoistVariableDeclaration(errorRecord);
+            hoistVariableDeclaration(returnMethod);
+            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
+            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
+                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
+                ts.createVariableDeclaration(result, /*type*/ undefined, next)
+            ]), node.expression), 2097152 /* NoHoisting */), 
+            /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), 
+            /*incrementor*/ ts.createAssignment(result, next), 
+            /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), 
+            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
+            return ts.createTry(ts.createBlock([
+                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel)
+            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
+                ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
+                    ts.createPropertyAssignment("error", catchVariable)
+                ])))
+            ]), 1 /* SingleLine */)), ts.createBlock([
+                ts.createTry(
+                /*tryBlock*/ ts.createBlock([
+                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */),
+                ]), 
+                /*catchClause*/ undefined, 
+                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
+                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
+                ]), 1 /* SingleLine */))
+            ]));
+        }
+        /**
+         * Visits an ObjectLiteralExpression with computed propety names.
+         *
+         * @param node An ObjectLiteralExpression node.
+         */
+        function visitObjectLiteralExpression(node) {
+            // We are here because a ComputedPropertyName was used somewhere in the expression.
+            var properties = node.properties;
+            var numProperties = properties.length;
+            // Find the first computed property.
+            // Everything until that point can be emitted as part of the initial object literal.
+            var numInitialProperties = numProperties;
+            var numInitialPropertiesWithoutYield = numProperties;
+            for (var i = 0; i < numProperties; i++) {
+                var property = properties[i];
+                if ((property.transformFlags & 16777216 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */)
+                    && i < numInitialPropertiesWithoutYield) {
+                    numInitialPropertiesWithoutYield = i;
+                }
+                if (property.name.kind === 144 /* ComputedPropertyName */) {
+                    numInitialProperties = i;
+                    break;
+                }
+            }
+            if (numInitialProperties !== numProperties) {
+                if (numInitialPropertiesWithoutYield < numInitialProperties) {
+                    numInitialProperties = numInitialPropertiesWithoutYield;
+                }
+                // For computed properties, we need to create a unique handle to the object
+                // literal so we can modify it without risking internal assignments tainting the object.
+                var temp = ts.createTempVariable(hoistVariableDeclaration);
+                // Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
+                var expressions = [];
+                var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */));
+                if (node.multiLine) {
+                    assignment.startsOnNewLine = true;
+                }
+                expressions.push(assignment);
+                addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
+                // We need to clone the temporary identifier so that we can write it on a
+                // new line
+                expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
+                return ts.inlineExpressions(expressions);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function shouldConvertIterationStatementBody(node) {
+            return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
+        }
+        /**
+         * Records constituents of name for the given variable to be hoisted in the outer scope.
+         */
+        function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
+            if (!state.hoistedLocalVariables) {
+                state.hoistedLocalVariables = [];
+            }
+            visit(node.name);
+            function visit(node) {
+                if (node.kind === 71 /* Identifier */) {
+                    state.hoistedLocalVariables.push(node);
+                }
+                else {
+                    for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
+                        var element = _a[_i];
+                        if (!ts.isOmittedExpression(element)) {
+                            visit(element.name);
+                        }
+                    }
+                }
+            }
+        }
+        function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert) {
+            if (!shouldConvertIterationStatementBody(node)) {
+                var saveAllowedNonLabeledJumps = void 0;
+                if (convertedLoopState) {
+                    // we get here if we are trying to emit normal loop loop inside converted loop
+                    // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
+                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
+                    convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
+                }
+                var result = convert
+                    ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined)
+                    : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
+                if (convertedLoopState) {
+                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
+                }
+                return result;
+            }
+            var functionName = ts.createUniqueName("_loop");
+            var loopInitializer;
+            switch (node.kind) {
+                case 214 /* ForStatement */:
+                case 215 /* ForInStatement */:
+                case 216 /* ForOfStatement */:
+                    var initializer = node.initializer;
+                    if (initializer && initializer.kind === 227 /* VariableDeclarationList */) {
+                        loopInitializer = initializer;
+                    }
+                    break;
+            }
+            // variables that will be passed to the loop as parameters
+            var loopParameters = [];
+            // variables declared in the loop initializer that will be changed inside the loop
+            var loopOutParameters = [];
+            if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) {
+                for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    processLoopVariableDeclaration(decl, loopParameters, loopOutParameters);
+                }
+            }
+            var outerConvertedLoopState = convertedLoopState;
+            convertedLoopState = { loopOutParameters: loopOutParameters };
+            if (outerConvertedLoopState) {
+                // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
+                // if outer converted loop has already accumulated some state - pass it through
+                if (outerConvertedLoopState.argumentsName) {
+                    // outer loop has already used 'arguments' so we've already have some name to alias it
+                    // use the same name in all nested loops
+                    convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName;
+                }
+                if (outerConvertedLoopState.thisName) {
+                    // outer loop has already used 'this' so we've already have some name to alias it
+                    // use the same name in all nested loops
+                    convertedLoopState.thisName = outerConvertedLoopState.thisName;
+                }
+                if (outerConvertedLoopState.hoistedLocalVariables) {
+                    // we've already collected some non-block scoped variable declarations in enclosing loop
+                    // use the same storage in nested loop
+                    convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables;
+                }
+            }
+            startLexicalEnvironment();
+            var loopBody = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
+            var lexicalEnvironment = endLexicalEnvironment();
+            var currentState = convertedLoopState;
+            convertedLoopState = outerConvertedLoopState;
+            if (loopOutParameters.length || lexicalEnvironment) {
+                var statements_4 = ts.isBlock(loopBody) ? loopBody.statements.slice() : [loopBody];
+                if (loopOutParameters.length) {
+                    copyOutParameters(loopOutParameters, 1 /* ToOutParameter */, statements_4);
+                }
+                ts.addRange(statements_4, lexicalEnvironment);
+                loopBody = ts.createBlock(statements_4, /*multiline*/ true);
+            }
+            if (ts.isBlock(loopBody)) {
+                loopBody.multiLine = true;
+            }
+            else {
+                loopBody = ts.createBlock([loopBody], /*multiline*/ true);
+            }
+            var containsYield = (node.statement.transformFlags & 16777216 /* ContainsYield */) !== 0;
+            var isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0;
+            var loopBodyFlags = 0;
+            if (currentState.containsLexicalThis) {
+                loopBodyFlags |= 8 /* CapturesThis */;
+            }
+            if (isAsyncBlockContainingAwait) {
+                loopBodyFlags |= 262144 /* AsyncFunctionBody */;
+            }
+            var convertedLoopVariable = ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(functionName, 
+                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
+                /*modifiers*/ undefined, containsYield ? ts.createToken(39 /* AsteriskToken */) : undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, loopParameters, 
+                /*type*/ undefined, loopBody), loopBodyFlags))
+            ]), 2097152 /* NoHoisting */));
+            var statements = [convertedLoopVariable];
+            var extraVariableDeclarations;
+            // propagate state from the inner loop to the outer loop if necessary
+            if (currentState.argumentsName) {
+                // if alias for arguments is set
+                if (outerConvertedLoopState) {
+                    // pass it to outer converted loop
+                    outerConvertedLoopState.argumentsName = currentState.argumentsName;
+                }
+                else {
+                    // this is top level converted loop and we need to create an alias for 'arguments' object
+                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.argumentsName, 
+                    /*type*/ undefined, ts.createIdentifier("arguments")));
+                }
+            }
+            if (currentState.thisName) {
+                // if alias for this is set
+                if (outerConvertedLoopState) {
+                    // pass it to outer converted loop
+                    outerConvertedLoopState.thisName = currentState.thisName;
+                }
+                else {
+                    // this is top level converted loop so we need to create an alias for 'this' here
+                    // NOTE:
+                    // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
+                    // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
+                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.thisName, 
+                    /*type*/ undefined, ts.createIdentifier("this")));
+                }
+            }
+            if (currentState.hoistedLocalVariables) {
+                // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
+                if (outerConvertedLoopState) {
+                    // pass them to outer converted loop
+                    outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables;
+                }
+                else {
+                    if (!extraVariableDeclarations) {
+                        extraVariableDeclarations = [];
+                    }
+                    // hoist collected variable declarations
+                    for (var _b = 0, _c = currentState.hoistedLocalVariables; _b < _c.length; _b++) {
+                        var identifier = _c[_b];
+                        extraVariableDeclarations.push(ts.createVariableDeclaration(identifier));
+                    }
+                }
+            }
+            // add extra variables to hold out parameters if necessary
+            if (loopOutParameters.length) {
+                if (!extraVariableDeclarations) {
+                    extraVariableDeclarations = [];
+                }
+                for (var _d = 0, loopOutParameters_1 = loopOutParameters; _d < loopOutParameters_1.length; _d++) {
+                    var outParam = loopOutParameters_1[_d];
+                    extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName));
+                }
+            }
+            // create variable statement to hold all introduced variable declarations
+            if (extraVariableDeclarations) {
+                statements.push(ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations)));
+            }
+            var convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield);
+            var loop;
+            if (convert) {
+                loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
+            }
+            else {
+                var clone_3 = ts.getMutableClone(node);
+                // clean statement part
+                clone_3.statement = undefined;
+                // visit childnodes to transform initializer/condition/incrementor parts
+                clone_3 = ts.visitEachChild(clone_3, visitor, context);
+                // set loop statement
+                clone_3.statement = ts.createBlock(convertedLoopBodyStatements, /*multiline*/ true);
+                // reset and re-aggregate the transform flags
+                clone_3.transformFlags = 0;
+                ts.aggregateTransformFlags(clone_3);
+                loop = ts.restoreEnclosingLabel(clone_3, outermostLabeledStatement, convertedLoopState && resetLabel);
+            }
+            statements.push(loop);
+            return statements;
+        }
+        function copyOutParameter(outParam, copyDirection) {
+            var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
+            var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
+            return ts.createBinary(target, 58 /* EqualsToken */, source);
+        }
+        function copyOutParameters(outParams, copyDirection, statements) {
+            for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) {
+                var outParam = outParams_1[_i];
+                statements.push(ts.createStatement(copyOutParameter(outParam, copyDirection)));
+            }
+        }
+        function generateCallToConvertedLoop(loopFunctionExpressionName, parameters, state, isAsyncBlockContainingAwait) {
+            var outerConvertedLoopState = convertedLoopState;
+            var statements = [];
+            // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
+            // simple loops are emitted as just 'loop()';
+            // NOTE: if loop uses only 'continue' it still will be emitted as simple loop
+            var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) &&
+                !state.labeledNonLocalBreaks &&
+                !state.labeledNonLocalContinues;
+            var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(parameters, function (p) { return p.name; }));
+            var callResult = isAsyncBlockContainingAwait
+                ? ts.createYield(ts.createToken(39 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
+                : call;
+            if (isSimpleLoop) {
+                statements.push(ts.createStatement(callResult));
+                copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements);
+            }
+            else {
+                var loopResultName = ts.createUniqueName("state");
+                var stateVariable = ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)]));
+                statements.push(stateVariable);
+                copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements);
+                if (state.nonLocalJumps & 8 /* Return */) {
+                    var returnStatement = void 0;
+                    if (outerConvertedLoopState) {
+                        outerConvertedLoopState.nonLocalJumps |= 8 /* Return */;
+                        returnStatement = ts.createReturn(loopResultName);
+                    }
+                    else {
+                        returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value"));
+                    }
+                    statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement));
+                }
+                if (state.nonLocalJumps & 2 /* Break */) {
+                    statements.push(ts.createIf(ts.createBinary(loopResultName, 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak()));
+                }
+                if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
+                    var caseClauses = [];
+                    processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
+                    processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
+                    statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses)));
+                }
+            }
+            return statements;
+        }
+        function setLabeledJump(state, isBreak, labelText, labelMarker) {
+            if (isBreak) {
+                if (!state.labeledNonLocalBreaks) {
+                    state.labeledNonLocalBreaks = ts.createMap();
+                }
+                state.labeledNonLocalBreaks.set(labelText, labelMarker);
+            }
+            else {
+                if (!state.labeledNonLocalContinues) {
+                    state.labeledNonLocalContinues = ts.createMap();
+                }
+                state.labeledNonLocalContinues.set(labelText, labelMarker);
+            }
+        }
+        function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
+            if (!table) {
+                return;
+            }
+            table.forEach(function (labelMarker, labelText) {
+                var statements = [];
+                // if there are no outer converted loop or outer label in question is located inside outer converted loop
+                // then emit labeled break\continue
+                // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
+                if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
+                    var label = ts.createIdentifier(labelText);
+                    statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label));
+                }
+                else {
+                    setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
+                    statements.push(ts.createReturn(loopResultName));
+                }
+                caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements));
+            });
+        }
+        function processLoopVariableDeclaration(decl, loopParameters, loopOutParameters) {
+            var name = decl.name;
+            if (ts.isBindingPattern(name)) {
+                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
+                    }
+                }
+            }
+            else {
+                loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
+                if (resolver.getNodeCheckFlags(decl) & 2097152 /* NeedsLoopOutParameter */) {
+                    var outParamName = ts.createUniqueName("out_" + ts.idText(name));
+                    loopOutParameters.push({ originalName: name, outParamName: outParamName });
+                }
+            }
+        }
+        /**
+         * Adds the members of an object literal to an array of expressions.
+         *
+         * @param expressions An array of expressions.
+         * @param node An ObjectLiteralExpression node.
+         * @param receiver The receiver for members of the ObjectLiteralExpression.
+         * @param numInitialNonComputedProperties The number of initial properties without
+         *                                        computed property names.
+         */
+        function addObjectLiteralMembers(expressions, node, receiver, start) {
+            var properties = node.properties;
+            var numProperties = properties.length;
+            for (var i = start; i < numProperties; i++) {
+                var property = properties[i];
+                switch (property.kind) {
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
+                        if (property === accessors.firstAccessor) {
+                            expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine));
+                        }
+                        break;
+                    case 151 /* MethodDeclaration */:
+                        expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
+                        break;
+                    case 261 /* PropertyAssignment */:
+                        expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
+                        break;
+                    case 262 /* ShorthandPropertyAssignment */:
+                        expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
+                        break;
+                    default:
+                        ts.Debug.failBadSyntaxKind(node);
+                        break;
+                }
+            }
+        }
+        /**
+         * Transforms a PropertyAssignment node into an expression.
+         *
+         * @param node The ObjectLiteralExpression that contains the PropertyAssignment.
+         * @param property The PropertyAssignment node.
+         * @param receiver The receiver for the assignment.
+         */
+        function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
+            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression));
+            ts.setTextRange(expression, property);
+            if (startsOnNewLine) {
+                expression.startsOnNewLine = true;
+            }
+            return expression;
+        }
+        /**
+         * Transforms a ShorthandPropertyAssignment node into an expression.
+         *
+         * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment.
+         * @param property The ShorthandPropertyAssignment node.
+         * @param receiver The receiver for the assignment.
+         */
+        function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
+            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name));
+            ts.setTextRange(expression, property);
+            if (startsOnNewLine) {
+                expression.startsOnNewLine = true;
+            }
+            return expression;
+        }
+        /**
+         * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression.
+         *
+         * @param node The ObjectLiteralExpression that contains the MethodDeclaration.
+         * @param method The MethodDeclaration node.
+         * @param receiver The receiver for the assignment.
+         */
+        function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
+            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
+            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container));
+            ts.setTextRange(expression, method);
+            if (startsOnNewLine) {
+                expression.startsOnNewLine = true;
+            }
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
+            return expression;
+        }
+        function visitCatchClause(node) {
+            var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
+            var updated;
+            ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
+            if (ts.isBindingPattern(node.variableDeclaration.name)) {
+                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
+                var newVariableDeclaration = ts.createVariableDeclaration(temp);
+                ts.setTextRange(newVariableDeclaration, node.variableDeclaration);
+                var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp);
+                var list = ts.createVariableDeclarationList(vars);
+                ts.setTextRange(list, node.variableDeclaration);
+                var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list);
+                updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
+            }
+            else {
+                updated = ts.visitEachChild(node, visitor, context);
+            }
+            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+            return updated;
+        }
+        function addStatementToStartOfBlock(block, statement) {
+            var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement);
+            return ts.updateBlock(block, [statement].concat(transformedStatements));
+        }
+        /**
+         * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
+         * PropertyAssignment.
+         *
+         * @param node A MethodDeclaration node.
+         */
+        function visitMethodDeclaration(node) {
+            // We should only get here for methods on an object literal with regular identifier names.
+            // Methods on classes are handled in visitClassDeclaration/visitClassExpression.
+            // Methods with computed property names are handled in visitObjectLiteralExpression.
+            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
+            var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
+            ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression));
+            return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), 
+            /*location*/ node);
+        }
+        /**
+         * Visits an AccessorDeclaration of an ObjectLiteralExpression.
+         *
+         * @param node An AccessorDeclaration node.
+         */
+        function visitAccessorDeclaration(node) {
+            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
+            var savedConvertedLoopState = convertedLoopState;
+            convertedLoopState = undefined;
+            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
+            var updated;
+            if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */) {
+                var parameters = ts.visitParameterList(node.parameters, visitor, context);
+                var body = transformFunctionBody(node);
+                if (node.kind === 153 /* GetAccessor */) {
+                    updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
+                }
+                else {
+                    updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
+                }
+            }
+            else {
+                updated = ts.visitEachChild(node, visitor, context);
+            }
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
+            convertedLoopState = savedConvertedLoopState;
+            return updated;
+        }
+        /**
+         * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment.
+         *
+         * @param node A ShorthandPropertyAssignment node.
+         */
+        function visitShorthandPropertyAssignment(node) {
+            return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), 
+            /*location*/ node);
+        }
+        function visitComputedPropertyName(node) {
+            var ancestorFacts = enterSubtree(0 /* ComputedPropertyNameExcludes */, 8192 /* ComputedPropertyNameIncludes */);
+            var updated = ts.visitEachChild(node, visitor, context);
+            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 32768 /* NewTargetInComputedPropertyName */ : 0 /* None */);
+            return updated;
+        }
+        /**
+         * Visits a YieldExpression node.
+         *
+         * @param node A YieldExpression node.
+         */
+        function visitYieldExpression(node) {
+            // `yield` expressions are transformed using the generators transformer.
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits an ArrayLiteralExpression that contains a spread element.
+         *
+         * @param node An ArrayLiteralExpression node.
+         */
+        function visitArrayLiteralExpression(node) {
+            if (node.transformFlags & 64 /* ES2015 */) {
+                // We are here because we contain a SpreadElementExpression.
+                return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine, /*hasTrailingComma*/ node.elements.hasTrailingComma);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a CallExpression that contains either a spread element or `super`.
+         *
+         * @param node a CallExpression.
+         */
+        function visitCallExpression(node) {
+            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
+                return visitTypeScriptClassWrapper(node);
+            }
+            if (node.transformFlags & 64 /* ES2015 */) {
+                return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
+            }
+            return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), 
+            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
+        }
+        function visitTypeScriptClassWrapper(node) {
+            // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer.
+            // The wrapper has a form similar to:
+            //
+            //  (function() {
+            //      class C { // 1
+            //      }
+            //      C.x = 1; // 2
+            //      return C;
+            //  }())
+            //
+            // When we transform the class, we end up with something like this:
+            //
+            //  (function () {
+            //      var C = (function () { // 3
+            //          function C() {
+            //          }
+            //          return C; // 4
+            //      }());
+            //      C.x = 1;
+            //      return C;
+            //  }())
+            //
+            // We want to simplify the two nested IIFEs to end up with something like this:
+            //
+            //  (function () {
+            //      function C() {
+            //      }
+            //      C.x = 1;
+            //      return C;
+            //  }())
+            // We skip any outer expressions in a number of places to get to the innermost
+            // expression, but we will restore them later to preserve comments and source maps.
+            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
+            // The class statements are the statements generated by visiting the first statement of the
+            // body (1), while all other statements are added to remainingStatements (2)
+            var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
+            var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1);
+            var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement);
+            // We know there is only one variable declaration here as we verified this in an
+            // earlier call to isTypeScriptClassWrapper
+            var variable = varStatement.declarationList.declarations[0];
+            var initializer = ts.skipOuterExpressions(variable.initializer);
+            // Under certain conditions, the 'ts' transformer may introduce a class alias, which
+            // we see as an assignment, for example:
+            //
+            //  (function () {
+            //      var C = C_1 = (function () {
+            //          function C() {
+            //          }
+            //          C.x = function () { return C_1; }
+            //          return C;
+            //      }());
+            //      C = C_1 = __decorate([dec], C);
+            //      return C;
+            //      var C_1;
+            //  }())
+            //
+            var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression);
+            // The underlying call (3) is another IIFE that may contain a '_super' argument.
+            var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression);
+            var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
+            var funcStatements = func.body.statements;
+            var classBodyStart = 0;
+            var classBodyEnd = -1;
+            var statements = [];
+            if (aliasAssignment) {
+                // If we have a class alias assignment, we need to move it to the down-level constructor
+                // function we generated for the class.
+                var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement);
+                if (extendsCall) {
+                    statements.push(extendsCall);
+                    classBodyStart++;
+                }
+                // The next statement is the function declaration.
+                statements.push(funcStatements[classBodyStart]);
+                classBodyStart++;
+                // Add the class alias following the declaration.
+                statements.push(ts.createStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier))));
+            }
+            // Find the trailing 'return' statement (4)
+            while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) {
+                classBodyEnd--;
+            }
+            // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4)
+            // as we already have one that has been introduced by the 'ts' transformer.
+            ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd);
+            if (classBodyEnd < -1) {
+                // If there were any hoisted declarations following the return statement, we should
+                // append them.
+                ts.addRange(statements, funcStatements, classBodyEnd + 1);
+            }
+            // Add the remaining statements of the outer wrapper.
+            ts.addRange(statements, remainingStatements);
+            // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it
+            // after the remaining statements from the 'ts' transformer.
+            ts.addRange(statements, classStatements, /*start*/ 1);
+            // Recreate any outer parentheses or partially-emitted expressions to preserve source map
+            // and comment locations.
+            return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, 
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, func.parameters, 
+            /*type*/ undefined, ts.updateBlock(func.body, statements))), 
+            /*typeArguments*/ undefined, call.arguments))));
+        }
+        function visitImmediateSuperCallInBody(node) {
+            return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false);
+        }
+        function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
+            // We are here either because SuperKeyword was used somewhere in the expression, or
+            // because we contain a SpreadElementExpression.
+            var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                ts.setEmitFlags(thisArg, 4 /* NoSubstitution */);
+            }
+            var resultingCall;
+            if (node.transformFlags & 524288 /* ContainsSpread */) {
+                // [source]
+                //      f(...a, b)
+                //      x.m(...a, b)
+                //      super(...a, b)
+                //      super.m(...a, b) // in static
+                //      super.m(...a, b) // in instance
+                //
+                // [output]
+                //      f.apply(void 0, a.concat([b]))
+                //      (_a = x).m.apply(_a, a.concat([b]))
+                //      _super.apply(this, a.concat([b]))
+                //      _super.m.apply(this, a.concat([b]))
+                //      _super.prototype.m.apply(this, a.concat([b]))
+                resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false));
+            }
+            else {
+                // [source]
+                //      super(a)
+                //      super.m(a) // in static
+                //      super.m(a) // in instance
+                //
+                // [output]
+                //      _super.call(this, a)
+                //      _super.m.call(this, a)
+                //      _super.prototype.m.call(this, a)
+                resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), 
+                /*location*/ node);
+            }
+            if (node.expression.kind === 97 /* SuperKeyword */) {
+                var actualThis = ts.createThis();
+                ts.setEmitFlags(actualThis, 4 /* NoSubstitution */);
+                var initializer = ts.createLogicalOr(resultingCall, actualThis);
+                resultingCall = assignToCapturedThis
+                    ? ts.createAssignment(ts.createIdentifier("_this"), initializer)
+                    : initializer;
+            }
+            return ts.setOriginalNode(resultingCall, node);
+        }
+        /**
+         * Visits a NewExpression that contains a spread element.
+         *
+         * @param node A NewExpression node.
+         */
+        function visitNewExpression(node) {
+            if (node.transformFlags & 524288 /* ContainsSpread */) {
+                // We are here because we contain a SpreadElementExpression.
+                // [source]
+                //      new C(...a)
+                //
+                // [output]
+                //      new ((_a = C).bind.apply(_a, [void 0].concat(a)))()
+                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
+                return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray([ts.createVoidZero()].concat(node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), 
+                /*typeArguments*/ undefined, []);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Transforms an array of Expression nodes that contains a SpreadExpression.
+         *
+         * @param elements The array of Expression nodes.
+         * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
+         * @param multiLine A value indicating whether the result should be emitted on multiple lines.
+         */
+        function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) {
+            // [source]
+            //      [a, ...b, c]
+            //
+            // [output]
+            //      [a].concat(b, [c])
+            // Map spans of spread expressions into their expressions and spans of other
+            // expressions into an array literal.
+            var numElements = elements.length;
+            var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) {
+                return visitPartition(partition, multiLine, hasTrailingComma && end === numElements);
+            }));
+            if (compilerOptions.downlevelIteration) {
+                if (segments.length === 1) {
+                    var firstSegment = segments[0];
+                    if (ts.isCallExpression(firstSegment)
+                        && ts.isIdentifier(firstSegment.expression)
+                        && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */)
+                        && firstSegment.expression.escapedText === "___spread") {
+                        return segments[0];
+                    }
+                }
+                return ts.createSpreadHelper(context, segments);
+            }
+            else {
+                if (segments.length === 1) {
+                    var firstElement = elements[0];
+                    return needsUniqueCopy && ts.isSpreadElement(firstElement) && firstElement.expression.kind !== 177 /* ArrayLiteralExpression */
+                        ? ts.createArraySlice(segments[0])
+                        : segments[0];
+                }
+                // Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
+                return ts.createArrayConcat(segments.shift(), segments);
+            }
+        }
+        function partitionSpread(node) {
+            return ts.isSpreadElement(node)
+                ? visitSpanOfSpreads
+                : visitSpanOfNonSpreads;
+        }
+        function visitSpanOfSpreads(chunk) {
+            return ts.map(chunk, visitExpressionOfSpread);
+        }
+        function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
+            return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine);
+        }
+        function visitSpreadElement(node) {
+            return ts.visitNode(node.expression, visitor, ts.isExpression);
+        }
+        /**
+         * Transforms the expression of a SpreadExpression node.
+         *
+         * @param node A SpreadExpression node.
+         */
+        function visitExpressionOfSpread(node) {
+            return ts.visitNode(node.expression, visitor, ts.isExpression);
+        }
+        /**
+         * Visits a template literal.
+         *
+         * @param node A template literal.
+         */
+        function visitTemplateLiteral(node) {
+            return ts.setTextRange(ts.createLiteral(node.text), node);
+        }
+        /**
+         * Visits a string literal with an extended unicode escape.
+         *
+         * @param node A string literal.
+         */
+        function visitStringLiteral(node) {
+            if (node.hasExtendedUnicodeEscape) {
+                return ts.setTextRange(ts.createLiteral(node.text), node);
+            }
+            return node;
+        }
+        /**
+         * Visits a binary or octal (ES6) numeric literal.
+         *
+         * @param node A string literal.
+         */
+        function visitNumericLiteral(node) {
+            if (node.numericLiteralFlags & 48 /* BinaryOrOctalSpecifier */) {
+                return ts.setTextRange(ts.createNumericLiteral(node.text), node);
+            }
+            return node;
+        }
+        /**
+         * Visits a TaggedTemplateExpression node.
+         *
+         * @param node A TaggedTemplateExpression node.
+         */
+        function visitTaggedTemplateExpression(node) {
+            // Visit the tag expression
+            var tag = ts.visitNode(node.tag, visitor, ts.isExpression);
+            // Build up the template arguments and the raw and cooked strings for the template.
+            // We start out with 'undefined' for the first argument and revisit later
+            // to avoid walking over the template string twice and shifting all our arguments over after the fact.
+            var templateArguments = [undefined];
+            var cookedStrings = [];
+            var rawStrings = [];
+            var template = node.template;
+            if (ts.isNoSubstitutionTemplateLiteral(template)) {
+                cookedStrings.push(ts.createLiteral(template.text));
+                rawStrings.push(getRawLiteral(template));
+            }
+            else {
+                cookedStrings.push(ts.createLiteral(template.head.text));
+                rawStrings.push(getRawLiteral(template.head));
+                for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) {
+                    var templateSpan = _a[_i];
+                    cookedStrings.push(ts.createLiteral(templateSpan.literal.text));
+                    rawStrings.push(getRawLiteral(templateSpan.literal));
+                    templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression));
+                }
+            }
+            var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings));
+            // Create a variable to cache the template object if we're in a module.
+            // Do not do this in the global scope, as any variable we currently generate could conflict with
+            // variables from outside of the current compilation. In the future, we can revisit this behavior.
+            if (ts.isExternalModule(currentSourceFile)) {
+                var tempVar = ts.createUniqueName("templateObject");
+                recordTaggedTemplateString(tempVar);
+                templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall));
+            }
+            else {
+                templateArguments[0] = helperCall;
+            }
+            return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments);
+        }
+        /**
+         * Creates an ES5 compatible literal from an ES6 template literal.
+         *
+         * @param node The ES6 template literal.
+         */
+        function getRawLiteral(node) {
+            // Find original source text, since we need to emit the raw strings of the tagged template.
+            // The raw strings contain the (escaped) strings of what the user wrote.
+            // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
+            var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+            // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
+            // thus we need to remove those characters.
+            // First template piece starts with "`", others with "}"
+            // Last template piece ends with "`", others with "${"
+            var isLast = node.kind === 13 /* NoSubstitutionTemplateLiteral */ || node.kind === 16 /* TemplateTail */;
+            text = text.substring(1, text.length - (isLast ? 1 : 2));
+            // Newline normalization:
+            // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
+            // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
+            text = text.replace(/\r\n?/g, "\n");
+            return ts.setTextRange(ts.createLiteral(text), node);
+        }
+        /**
+         * Visits a TemplateExpression node.
+         *
+         * @param node A TemplateExpression node.
+         */
+        function visitTemplateExpression(node) {
+            var expressions = [];
+            addTemplateHead(expressions, node);
+            addTemplateSpans(expressions, node);
+            // createAdd will check if each expression binds less closely than binary '+'.
+            // If it does, it wraps the expression in parentheses. Otherwise, something like
+            //    `abc${ 1 << 2 }`
+            // becomes
+            //    "abc" + 1 << 2 + ""
+            // which is really
+            //    ("abc" + 1) << (2 + "")
+            // rather than
+            //    "abc" + (1 << 2) + ""
+            var expression = ts.reduceLeft(expressions, ts.createAdd);
+            if (ts.nodeIsSynthesized(expression)) {
+                expression.pos = node.pos;
+                expression.end = node.end;
+            }
+            return expression;
+        }
+        /**
+         * Gets a value indicating whether we need to include the head of a TemplateExpression.
+         *
+         * @param node A TemplateExpression node.
+         */
+        function shouldAddTemplateHead(node) {
+            // If this expression has an empty head literal and the first template span has a non-empty
+            // literal, then emitting the empty head literal is not necessary.
+            //     `${ foo } and ${ bar }`
+            // can be emitted as
+            //     foo + " and " + bar
+            // This is because it is only required that one of the first two operands in the emit
+            // output must be a string literal, so that the other operand and all following operands
+            // are forced into strings.
+            //
+            // If the first template span has an empty literal, then the head must still be emitted.
+            //     `${ foo }${ bar }`
+            // must still be emitted as
+            //     "" + foo + bar
+            // There is always atleast one templateSpan in this code path, since
+            // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
+            ts.Debug.assert(node.templateSpans.length !== 0);
+            return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
+        }
+        /**
+         * Adds the head of a TemplateExpression to an array of expressions.
+         *
+         * @param expressions An array of expressions.
+         * @param node A TemplateExpression node.
+         */
+        function addTemplateHead(expressions, node) {
+            if (!shouldAddTemplateHead(node)) {
+                return;
+            }
+            expressions.push(ts.createLiteral(node.head.text));
+        }
+        /**
+         * Visits and adds the template spans of a TemplateExpression to an array of expressions.
+         *
+         * @param expressions An array of expressions.
+         * @param node A TemplateExpression node.
+         */
+        function addTemplateSpans(expressions, node) {
+            for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) {
+                var span_6 = _a[_i];
+                expressions.push(ts.visitNode(span_6.expression, visitor, ts.isExpression));
+                // Only emit if the literal is non-empty.
+                // The binary '+' operator is left-associative, so the first string concatenation
+                // with the head will force the result up to this point to be a string.
+                // Emitting a '+ ""' has no semantic effect for middles and tails.
+                if (span_6.literal.text.length !== 0) {
+                    expressions.push(ts.createLiteral(span_6.literal.text));
+                }
+            }
+        }
+        /**
+         * Visits the `super` keyword
+         */
+        function visitSuperKeyword(isExpressionOfCall) {
+            return hierarchyFacts & 8 /* NonStaticClassElement */
+                && !isExpressionOfCall
+                ? ts.createPropertyAccess(ts.createIdentifier("_super"), "prototype")
+                : ts.createIdentifier("_super");
+        }
+        function visitMetaProperty(node) {
+            if (node.keywordToken === 94 /* NewKeyword */ && node.name.escapedText === "target") {
+                if (hierarchyFacts & 8192 /* ComputedPropertyName */) {
+                    hierarchyFacts |= 32768 /* NewTargetInComputedPropertyName */;
+                }
+                else {
+                    hierarchyFacts |= 16384 /* NewTarget */;
+                }
+                return ts.createIdentifier("_newTarget");
+            }
+            return node;
+        }
+        /**
+         * Called by the printer just before a node is printed.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to be printed.
+         * @param emitCallback The callback used to emit the node.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) {
+                // If we are tracking a captured `this`, keep track of the enclosing function.
+                var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */
+                    ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */
+                    : 65 /* FunctionIncludes */);
+                previousOnEmitNode(hint, node, emitCallback);
+                exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
+                return;
+            }
+            previousOnEmitNode(hint, node, emitCallback);
+        }
+        /**
+         * Enables a more costly code path for substitutions when we determine a source file
+         * contains block-scoped bindings (e.g. `let` or `const`).
+         */
+        function enableSubstitutionsForBlockScopedBindings() {
+            if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
+                enabledSubstitutions |= 2 /* BlockScopedBindings */;
+                context.enableSubstitution(71 /* Identifier */);
+            }
+        }
+        /**
+         * Enables a more costly code path for substitutions when we determine a source file
+         * contains a captured `this`.
+         */
+        function enableSubstitutionsForCapturedThis() {
+            if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
+                enabledSubstitutions |= 1 /* CapturedThis */;
+                context.enableSubstitution(99 /* ThisKeyword */);
+                context.enableEmitNotification(152 /* Constructor */);
+                context.enableEmitNotification(151 /* MethodDeclaration */);
+                context.enableEmitNotification(153 /* GetAccessor */);
+                context.enableEmitNotification(154 /* SetAccessor */);
+                context.enableEmitNotification(187 /* ArrowFunction */);
+                context.enableEmitNotification(186 /* FunctionExpression */);
+                context.enableEmitNotification(228 /* FunctionDeclaration */);
+            }
+        }
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint The context for the emitter.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (hint === 1 /* Expression */) {
+                return substituteExpression(node);
+            }
+            if (ts.isIdentifier(node)) {
+                return substituteIdentifier(node);
+            }
+            return node;
+        }
+        /**
+         * Hooks substitutions for non-expression identifiers.
+         */
+        function substituteIdentifier(node) {
+            // Only substitute the identifier if we have enabled substitutions for block-scoped
+            // bindings.
+            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
+                var original = ts.getParseTreeNode(node, ts.isIdentifier);
+                if (original && isNameOfDeclarationWithCollidingName(original)) {
+                    return ts.setTextRange(ts.getGeneratedNameForNode(original), node);
+                }
+            }
+            return node;
+        }
+        /**
+         * Determines whether a name is the name of a declaration with a colliding name.
+         * NOTE: This function expects to be called with an original source tree node.
+         *
+         * @param node An original source tree node.
+         */
+        function isNameOfDeclarationWithCollidingName(node) {
+            var parent = node.parent;
+            switch (parent.kind) {
+                case 176 /* BindingElement */:
+                case 229 /* ClassDeclaration */:
+                case 232 /* EnumDeclaration */:
+                case 226 /* VariableDeclaration */:
+                    return parent.name === node
+                        && resolver.isDeclarationWithCollidingName(parent);
+            }
+            return false;
+        }
+        /**
+         * Substitutes an expression.
+         *
+         * @param node An Expression node.
+         */
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return substituteExpressionIdentifier(node);
+                case 99 /* ThisKeyword */:
+                    return substituteThisKeyword(node);
+            }
+            return node;
+        }
+        /**
+         * Substitutes an expression identifier.
+         *
+         * @param node An Identifier node.
+         */
+        function substituteExpressionIdentifier(node) {
+            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
+                var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
+                if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
+                    return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node);
+                }
+            }
+            return node;
+        }
+        function isPartOfClassBody(declaration, node) {
+            var currentNode = ts.getParseTreeNode(node);
+            if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
+                // if the node has no correlation to a parse tree node, its definitely not
+                // part of the body.
+                // if the node is outside of the document range of the declaration, its
+                // definitely not part of the body.
+                return false;
+            }
+            var blockScope = ts.getEnclosingBlockScopeContainer(declaration);
+            while (currentNode) {
+                if (currentNode === blockScope || currentNode === declaration) {
+                    // if we are in the enclosing block scope of the declaration, we are definitely
+                    // not inside the class body.
+                    return false;
+                }
+                if (ts.isClassElement(currentNode) && currentNode.parent === declaration) {
+                    return true;
+                }
+                currentNode = currentNode.parent;
+            }
+            return false;
+        }
+        /**
+         * Substitutes `this` when contained within an arrow function.
+         *
+         * @param node The ThisKeyword node.
+         */
+        function substituteThisKeyword(node) {
+            if (enabledSubstitutions & 1 /* CapturedThis */
+                && hierarchyFacts & 16 /* CapturesThis */) {
+                return ts.setTextRange(ts.createIdentifier("_this"), node);
+            }
+            return node;
+        }
+        function getClassMemberPrefix(node, member) {
+            return ts.hasModifier(member, 32 /* Static */)
+                ? ts.getInternalName(node)
+                : ts.createPropertyAccess(ts.getInternalName(node), "prototype");
+        }
+        function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
+            if (!constructor || !hasExtendsClause) {
+                return false;
+            }
+            if (ts.some(constructor.parameters)) {
+                return false;
+            }
+            var statement = ts.firstOrUndefined(constructor.body.statements);
+            if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 210 /* ExpressionStatement */) {
+                return false;
+            }
+            var statementExpression = statement.expression;
+            if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 181 /* CallExpression */) {
+                return false;
+            }
+            var callTarget = statementExpression.expression;
+            if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 97 /* SuperKeyword */) {
+                return false;
+            }
+            var callArgument = ts.singleOrUndefined(statementExpression.arguments);
+            if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 198 /* SpreadElement */) {
+                return false;
+            }
+            var expression = callArgument.expression;
+            return ts.isIdentifier(expression) && expression.escapedText === "arguments";
+        }
+    }
+    ts.transformES2015 = transformES2015;
+    function createExtendsHelper(context, name) {
+        context.requestEmitHelper(extendsHelper);
+        return ts.createCall(ts.getHelperName("__extends"), 
+        /*typeArguments*/ undefined, [
+            name,
+            ts.createIdentifier("_super")
+        ]);
+    }
+    function createTemplateObjectHelper(context, cooked, raw) {
+        context.requestEmitHelper(templateObjectHelper);
+        return ts.createCall(ts.getHelperName("__makeTemplateObject"), 
+        /*typeArguments*/ undefined, [
+            cooked,
+            raw
+        ]);
+    }
+    var extendsHelper = {
+        name: "typescript:extends",
+        scoped: false,
+        priority: 0,
+        text: "\n            var __extends = (this && this.__extends) || (function () {\n                var extendStatics = Object.setPrototypeOf ||\n                    ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n                    function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n                return function (d, b) {\n                    extendStatics(d, b);\n                    function __() { this.constructor = d; }\n                    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n                };\n            })();"
+    };
+    var templateObjectHelper = {
+        name: "typescript:makeTemplateObject",
+        scoped: false,
+        priority: 0,
+        text: "\n            var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n                if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n                return cooked;\n            };"
+    };
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    /**
+     * Transforms ES5 syntax into ES3 syntax.
+     *
+     * @param context Context and state information for the transformation.
+     */
+    function transformES5(context) {
+        var compilerOptions = context.getCompilerOptions();
+        // enable emit notification only if using --jsx preserve or react-native
+        var previousOnEmitNode;
+        var noSubstitution;
+        if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) {
+            previousOnEmitNode = context.onEmitNode;
+            context.onEmitNode = onEmitNode;
+            context.enableEmitNotification(251 /* JsxOpeningElement */);
+            context.enableEmitNotification(252 /* JsxClosingElement */);
+            context.enableEmitNotification(250 /* JsxSelfClosingElement */);
+            noSubstitution = [];
+        }
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        context.onSubstituteNode = onSubstituteNode;
+        context.enableSubstitution(179 /* PropertyAccessExpression */);
+        context.enableSubstitution(261 /* PropertyAssignment */);
+        return transformSourceFile;
+        /**
+         * Transforms an ES5 source file to ES3.
+         *
+         * @param node A SourceFile
+         */
+        function transformSourceFile(node) {
+            return node;
+        }
+        /**
+         * Called by the printer just before a node is printed.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emitCallback A callback used to emit the node.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            switch (node.kind) {
+                case 251 /* JsxOpeningElement */:
+                case 252 /* JsxClosingElement */:
+                case 250 /* JsxSelfClosingElement */:
+                    var tagName = node.tagName;
+                    noSubstitution[ts.getOriginalNodeId(tagName)] = true;
+                    break;
+            }
+            previousOnEmitNode(hint, node, emitCallback);
+        }
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            if (node.id && noSubstitution && noSubstitution[node.id]) {
+                return previousOnSubstituteNode(hint, node);
+            }
+            node = previousOnSubstituteNode(hint, node);
+            if (ts.isPropertyAccessExpression(node)) {
+                return substitutePropertyAccessExpression(node);
+            }
+            else if (ts.isPropertyAssignment(node)) {
+                return substitutePropertyAssignment(node);
+            }
+            return node;
+        }
+        /**
+         * Substitutes a PropertyAccessExpression whose name is a reserved word.
+         *
+         * @param node A PropertyAccessExpression
+         */
+        function substitutePropertyAccessExpression(node) {
+            var literalName = trySubstituteReservedName(node.name);
+            if (literalName) {
+                return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node);
+            }
+            return node;
+        }
+        /**
+         * Substitutes a PropertyAssignment whose name is a reserved word.
+         *
+         * @param node A PropertyAssignment
+         */
+        function substitutePropertyAssignment(node) {
+            var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name);
+            if (literalName) {
+                return ts.updatePropertyAssignment(node, literalName, node.initializer);
+            }
+            return node;
+        }
+        /**
+         * If an identifier name is a reserved word, returns a string literal for the name.
+         *
+         * @param name An Identifier
+         */
+        function trySubstituteReservedName(name) {
+            var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined);
+            if (token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */) {
+                return ts.setTextRange(ts.createLiteral(name), name);
+            }
+            return undefined;
+        }
+    }
+    ts.transformES5 = transformES5;
+})(ts || (ts = {}));
+/// <reference path="../factory.ts" />
+/// <reference path="../visitor.ts" />
+// Transforms generator functions into a compatible ES5 representation with similar runtime
+// semantics. This is accomplished by first transforming the body of each generator
+// function into an intermediate representation that is the compiled into a JavaScript
+// switch statement.
+//
+// Many functions in this transformer will contain comments indicating the expected
+// intermediate representation. For illustrative purposes, the following intermediate
+// language is used to define this intermediate representation:
+//
+//  .nop                            - Performs no operation.
+//  .local NAME, ...                - Define local variable declarations.
+//  .mark LABEL                     - Mark the location of a label.
+//  .br LABEL                       - Jump to a label. If jumping out of a protected
+//                                    region, all .finally blocks are executed.
+//  .brtrue LABEL, (x)              - Jump to a label IIF the expression `x` is truthy.
+//                                    If jumping out of a protected region, all .finally
+//                                    blocks are executed.
+//  .brfalse LABEL, (x)             - Jump to a label IIF the expression `x` is falsey.
+//                                    If jumping out of a protected region, all .finally
+//                                    blocks are executed.
+//  .yield (x)                      - Yield the value of the optional expression `x`.
+//                                    Resume at the next label.
+//  .yieldstar (x)                  - Delegate yield to the value of the optional
+//                                    expression `x`. Resume at the next label.
+//                                    NOTE: `x` must be an Iterator, not an Iterable.
+//  .loop CONTINUE, BREAK           - Marks the beginning of a loop. Any "continue" or
+//                                    "break" abrupt completions jump to the CONTINUE or
+//                                    BREAK labels, respectively.
+//  .endloop                        - Marks the end of a loop.
+//  .with (x)                       - Marks the beginning of a WithStatement block, using
+//                                    the supplied expression.
+//  .endwith                        - Marks the end of a WithStatement.
+//  .switch                         - Marks the beginning of a SwitchStatement.
+//  .endswitch                      - Marks the end of a SwitchStatement.
+//  .labeled NAME                   - Marks the beginning of a LabeledStatement with the
+//                                    supplied name.
+//  .endlabeled                     - Marks the end of a LabeledStatement.
+//  .try TRY, CATCH, FINALLY, END   - Marks the beginning of a protected region, and the
+//                                    labels for each block.
+//  .catch (x)                      - Marks the beginning of a catch block.
+//  .finally                        - Marks the beginning of a finally block.
+//  .endfinally                     - Marks the end of a finally block.
+//  .endtry                         - Marks the end of a protected region.
+//  .throw (x)                      - Throws the value of the expression `x`.
+//  .return (x)                     - Returns the value of the expression `x`.
+//
+// In addition, the illustrative intermediate representation introduces some special
+// variables:
+//
+//  %sent%                          - Either returns the next value sent to the generator,
+//                                    returns the result of a delegated yield, or throws
+//                                    the exception sent to the generator.
+//  %error%                         - Returns the value of the current exception in a
+//                                    catch block.
+//
+// This intermediate representation is then compiled into JavaScript syntax. The resulting
+// compilation output looks something like the following:
+//
+//  function f() {
+//      var /*locals*/;
+//      /*functions*/
+//      return __generator(function (state) {
+//          switch (state.label) {
+//              /*cases per label*/
+//          }
+//      });
+//  }
+//
+// Each of the above instructions corresponds to JavaScript emit similar to the following:
+//
+//  .local NAME                   | var NAME;
+// -------------------------------|----------------------------------------------
+//  .mark LABEL                   | case LABEL:
+// -------------------------------|----------------------------------------------
+//  .br LABEL                     |     return [3 /*break*/, LABEL];
+// -------------------------------|----------------------------------------------
+//  .brtrue LABEL, (x)            |     if (x) return [3 /*break*/, LABEL];
+// -------------------------------|----------------------------------------------
+//  .brfalse LABEL, (x)           |     if (!(x)) return [3, /*break*/, LABEL];
+// -------------------------------|----------------------------------------------
+//  .yield (x)                    |     return [4 /*yield*/, x];
+//  .mark RESUME                  | case RESUME:
+//      a = %sent%;               |     a = state.sent();
+// -------------------------------|----------------------------------------------
+//  .yieldstar (x)                |     return [5 /*yield**/, x];
+//  .mark RESUME                  | case RESUME:
+//      a = %sent%;               |     a = state.sent();
+// -------------------------------|----------------------------------------------
+//  .with (_a)                    |     with (_a) {
+//      a();                      |         a();
+//                                |     }
+//                                |     state.label = LABEL;
+//  .mark LABEL                   | case LABEL:
+//                                |     with (_a) {
+//      b();                      |         b();
+//                                |     }
+//  .endwith                      |
+// -------------------------------|----------------------------------------------
+//                                | case 0:
+//                                |     state.trys = [];
+//                                | ...
+//  .try TRY, CATCH, FINALLY, END |
+//  .mark TRY                     | case TRY:
+//                                |     state.trys.push([TRY, CATCH, FINALLY, END]);
+//  .nop                          |
+//      a();                      |     a();
+//  .br END                       |     return [3 /*break*/, END];
+//  .catch (e)                    |
+//  .mark CATCH                   | case CATCH:
+//                                |     e = state.sent();
+//      b();                      |     b();
+//  .br END                       |     return [3 /*break*/, END];
+//  .finally                      |
+//  .mark FINALLY                 | case FINALLY:
+//      c();                      |     c();
+//  .endfinally                   |     return [7 /*endfinally*/];
+//  .endtry                       |
+//  .mark END                     | case END:
+/*@internal*/
+var ts;
+(function (ts) {
+    var OpCode;
+    (function (OpCode) {
+        OpCode[OpCode["Nop"] = 0] = "Nop";
+        OpCode[OpCode["Statement"] = 1] = "Statement";
+        OpCode[OpCode["Assign"] = 2] = "Assign";
+        OpCode[OpCode["Break"] = 3] = "Break";
+        OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue";
+        OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse";
+        OpCode[OpCode["Yield"] = 6] = "Yield";
+        OpCode[OpCode["YieldStar"] = 7] = "YieldStar";
+        OpCode[OpCode["Return"] = 8] = "Return";
+        OpCode[OpCode["Throw"] = 9] = "Throw";
+        OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block
+    })(OpCode || (OpCode = {}));
+    // whether a generated code block is opening or closing at the current operation for a FunctionBuilder
+    var BlockAction;
+    (function (BlockAction) {
+        BlockAction[BlockAction["Open"] = 0] = "Open";
+        BlockAction[BlockAction["Close"] = 1] = "Close";
+    })(BlockAction || (BlockAction = {}));
+    // the kind for a generated code block in a FunctionBuilder
+    var CodeBlockKind;
+    (function (CodeBlockKind) {
+        CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception";
+        CodeBlockKind[CodeBlockKind["With"] = 1] = "With";
+        CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch";
+        CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop";
+        CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled";
+    })(CodeBlockKind || (CodeBlockKind = {}));
+    // the state for a generated code exception block
+    var ExceptionBlockState;
+    (function (ExceptionBlockState) {
+        ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try";
+        ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch";
+        ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally";
+        ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done";
+    })(ExceptionBlockState || (ExceptionBlockState = {}));
+    // NOTE: changes to this enum should be reflected in the __generator helper.
+    var Instruction;
+    (function (Instruction) {
+        Instruction[Instruction["Next"] = 0] = "Next";
+        Instruction[Instruction["Throw"] = 1] = "Throw";
+        Instruction[Instruction["Return"] = 2] = "Return";
+        Instruction[Instruction["Break"] = 3] = "Break";
+        Instruction[Instruction["Yield"] = 4] = "Yield";
+        Instruction[Instruction["YieldStar"] = 5] = "YieldStar";
+        Instruction[Instruction["Catch"] = 6] = "Catch";
+        Instruction[Instruction["Endfinally"] = 7] = "Endfinally";
+    })(Instruction || (Instruction = {}));
+    function getInstructionName(instruction) {
+        switch (instruction) {
+            case 2 /* Return */: return "return";
+            case 3 /* Break */: return "break";
+            case 4 /* Yield */: return "yield";
+            case 5 /* YieldStar */: return "yield*";
+            case 7 /* Endfinally */: return "endfinally";
+        }
+    }
+    function transformGenerators(context) {
+        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var compilerOptions = context.getCompilerOptions();
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var resolver = context.getEmitResolver();
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        context.onSubstituteNode = onSubstituteNode;
+        var renamedCatchVariables;
+        var renamedCatchVariableDeclarations;
+        var inGeneratorFunctionBody;
+        var inStatementContainingYield;
+        // The following three arrays store information about generated code blocks.
+        // All three arrays are correlated by their index. This approach is used over allocating
+        // objects to store the same information to avoid GC overhead.
+        //
+        var blocks; // Information about the code block
+        var blockOffsets; // The operation offset at which a code block begins or ends
+        var blockActions; // Whether the code block is opened or closed
+        var blockStack; // A stack of currently open code blocks
+        // Labels are used to mark locations in the code that can be the target of a Break (jump)
+        // operation. These are translated into case clauses in a switch statement.
+        // The following two arrays are correlated by their index. This approach is used over
+        // allocating objects to store the same information to avoid GC overhead.
+        //
+        var labelOffsets; // The operation offset at which the label is defined.
+        var labelExpressions; // The NumericLiteral nodes bound to each label.
+        var nextLabelId = 1; // The next label id to use.
+        // Operations store information about generated code for the function body. This
+        // Includes things like statements, assignments, breaks (jumps), and yields.
+        // The following three arrays are correlated by their index. This approach is used over
+        // allocating objects to store the same information to avoid GC overhead.
+        //
+        var operations; // The operation to perform.
+        var operationArguments; // The arguments to the operation.
+        var operationLocations; // The source map location for the operation.
+        var state; // The name of the state object used by the generator at runtime.
+        // The following variables store information used by the `build` function:
+        //
+        var blockIndex = 0; // The index of the current block.
+        var labelNumber = 0; // The current label number.
+        var labelNumbers;
+        var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue).
+        var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw).
+        var clauses; // The case clauses generated for labels.
+        var statements; // The statements for the current label.
+        var exceptionBlockStack; // A stack of containing exception blocks.
+        var currentExceptionBlock; // The current exception block.
+        var withBlockStack; // A stack containing `with` blocks.
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile || (node.transformFlags & 512 /* ContainsGenerator */) === 0) {
+                return node;
+            }
+            var visited = ts.visitEachChild(node, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        }
+        /**
+         * Visits a node.
+         *
+         * @param node The node to visit.
+         */
+        function visitor(node) {
+            var transformFlags = node.transformFlags;
+            if (inStatementContainingYield) {
+                return visitJavaScriptInStatementContainingYield(node);
+            }
+            else if (inGeneratorFunctionBody) {
+                return visitJavaScriptInGeneratorFunctionBody(node);
+            }
+            else if (transformFlags & 256 /* Generator */) {
+                return visitGenerator(node);
+            }
+            else if (transformFlags & 512 /* ContainsGenerator */) {
+                return ts.visitEachChild(node, visitor, context);
+            }
+            else {
+                return node;
+            }
+        }
+        /**
+         * Visits a node that is contained within a statement that contains yield.
+         *
+         * @param node The node to visit.
+         */
+        function visitJavaScriptInStatementContainingYield(node) {
+            switch (node.kind) {
+                case 212 /* DoStatement */:
+                    return visitDoStatement(node);
+                case 213 /* WhileStatement */:
+                    return visitWhileStatement(node);
+                case 221 /* SwitchStatement */:
+                    return visitSwitchStatement(node);
+                case 222 /* LabeledStatement */:
+                    return visitLabeledStatement(node);
+                default:
+                    return visitJavaScriptInGeneratorFunctionBody(node);
+            }
+        }
+        /**
+         * Visits a node that is contained within a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitJavaScriptInGeneratorFunctionBody(node) {
+            switch (node.kind) {
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 186 /* FunctionExpression */:
+                    return visitFunctionExpression(node);
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return visitAccessorDeclaration(node);
+                case 208 /* VariableStatement */:
+                    return visitVariableStatement(node);
+                case 214 /* ForStatement */:
+                    return visitForStatement(node);
+                case 215 /* ForInStatement */:
+                    return visitForInStatement(node);
+                case 218 /* BreakStatement */:
+                    return visitBreakStatement(node);
+                case 217 /* ContinueStatement */:
+                    return visitContinueStatement(node);
+                case 219 /* ReturnStatement */:
+                    return visitReturnStatement(node);
+                default:
+                    if (node.transformFlags & 16777216 /* ContainsYield */) {
+                        return visitJavaScriptContainingYield(node);
+                    }
+                    else if (node.transformFlags & (512 /* ContainsGenerator */ | 33554432 /* ContainsHoistedDeclarationOrCompletion */)) {
+                        return ts.visitEachChild(node, visitor, context);
+                    }
+                    else {
+                        return node;
+                    }
+            }
+        }
+        /**
+         * Visits a node that contains a YieldExpression.
+         *
+         * @param node The node to visit.
+         */
+        function visitJavaScriptContainingYield(node) {
+            switch (node.kind) {
+                case 194 /* BinaryExpression */:
+                    return visitBinaryExpression(node);
+                case 195 /* ConditionalExpression */:
+                    return visitConditionalExpression(node);
+                case 197 /* YieldExpression */:
+                    return visitYieldExpression(node);
+                case 177 /* ArrayLiteralExpression */:
+                    return visitArrayLiteralExpression(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return visitObjectLiteralExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return visitElementAccessExpression(node);
+                case 181 /* CallExpression */:
+                    return visitCallExpression(node);
+                case 182 /* NewExpression */:
+                    return visitNewExpression(node);
+                default:
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        /**
+         * Visits a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitGenerator(node) {
+            switch (node.kind) {
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 186 /* FunctionExpression */:
+                    return visitFunctionExpression(node);
+                default:
+                    ts.Debug.failBadSyntaxKind(node);
+                    return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        /**
+         * Visits a function declaration.
+         *
+         * This will be called when one of the following conditions are met:
+         * - The function declaration is a generator function.
+         * - The function declaration is contained within the body of a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionDeclaration(node) {
+            // Currently, we only support generators that were originally async functions.
+            if (node.asteriskToken) {
+                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
+                /*decorators*/ undefined, node.modifiers, 
+                /*asteriskToken*/ undefined, node.name, 
+                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
+                /*location*/ node), node);
+            }
+            else {
+                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
+                var savedInStatementContainingYield = inStatementContainingYield;
+                inGeneratorFunctionBody = false;
+                inStatementContainingYield = false;
+                node = ts.visitEachChild(node, visitor, context);
+                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
+                inStatementContainingYield = savedInStatementContainingYield;
+            }
+            if (inGeneratorFunctionBody) {
+                // Function declarations in a generator function body are hoisted
+                // to the top of the lexical scope and elided from the current statement.
+                hoistFunctionDeclaration(node);
+                return undefined;
+            }
+            else {
+                return node;
+            }
+        }
+        /**
+         * Visits a function expression.
+         *
+         * This will be called when one of the following conditions are met:
+         * - The function expression is a generator function.
+         * - The function expression is contained within the body of a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionExpression(node) {
+            // Currently, we only support generators that were originally async functions.
+            if (node.asteriskToken) {
+                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
+                /*modifiers*/ undefined, 
+                /*asteriskToken*/ undefined, node.name, 
+                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
+                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
+                /*location*/ node), node);
+            }
+            else {
+                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
+                var savedInStatementContainingYield = inStatementContainingYield;
+                inGeneratorFunctionBody = false;
+                inStatementContainingYield = false;
+                node = ts.visitEachChild(node, visitor, context);
+                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
+                inStatementContainingYield = savedInStatementContainingYield;
+            }
+            return node;
+        }
+        /**
+         * Visits a get or set accessor declaration.
+         *
+         * This will be called when one of the following conditions are met:
+         * - The accessor is contained within the body of a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitAccessorDeclaration(node) {
+            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
+            var savedInStatementContainingYield = inStatementContainingYield;
+            inGeneratorFunctionBody = false;
+            inStatementContainingYield = false;
+            node = ts.visitEachChild(node, visitor, context);
+            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
+            inStatementContainingYield = savedInStatementContainingYield;
+            return node;
+        }
+        /**
+         * Transforms the body of a generator function declaration.
+         *
+         * @param node The function body to transform.
+         */
+        function transformGeneratorFunctionBody(body) {
+            // Save existing generator state
+            var statements = [];
+            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
+            var savedInStatementContainingYield = inStatementContainingYield;
+            var savedBlocks = blocks;
+            var savedBlockOffsets = blockOffsets;
+            var savedBlockActions = blockActions;
+            var savedBlockStack = blockStack;
+            var savedLabelOffsets = labelOffsets;
+            var savedLabelExpressions = labelExpressions;
+            var savedNextLabelId = nextLabelId;
+            var savedOperations = operations;
+            var savedOperationArguments = operationArguments;
+            var savedOperationLocations = operationLocations;
+            var savedState = state;
+            // Initialize generator state
+            inGeneratorFunctionBody = true;
+            inStatementContainingYield = false;
+            blocks = undefined;
+            blockOffsets = undefined;
+            blockActions = undefined;
+            blockStack = undefined;
+            labelOffsets = undefined;
+            labelExpressions = undefined;
+            nextLabelId = 1;
+            operations = undefined;
+            operationArguments = undefined;
+            operationLocations = undefined;
+            state = ts.createTempVariable(/*recordTempVariable*/ undefined);
+            // Build the generator
+            resumeLexicalEnvironment();
+            var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
+            transformAndEmitStatements(body.statements, statementOffset);
+            var buildResult = build();
+            ts.addRange(statements, endLexicalEnvironment());
+            statements.push(ts.createReturn(buildResult));
+            // Restore previous generator state
+            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
+            inStatementContainingYield = savedInStatementContainingYield;
+            blocks = savedBlocks;
+            blockOffsets = savedBlockOffsets;
+            blockActions = savedBlockActions;
+            blockStack = savedBlockStack;
+            labelOffsets = savedLabelOffsets;
+            labelExpressions = savedLabelExpressions;
+            nextLabelId = savedNextLabelId;
+            operations = savedOperations;
+            operationArguments = savedOperationArguments;
+            operationLocations = savedOperationLocations;
+            state = savedState;
+            return ts.setTextRange(ts.createBlock(statements, body.multiLine), body);
+        }
+        /**
+         * Visits a variable statement.
+         *
+         * This will be called when one of the following conditions are met:
+         * - The variable statement is contained within the body of a generator function.
+         *
+         * @param node The node to visit.
+         */
+        function visitVariableStatement(node) {
+            if (node.transformFlags & 16777216 /* ContainsYield */) {
+                transformAndEmitVariableDeclarationList(node.declarationList);
+                return undefined;
+            }
+            else {
+                // Do not hoist custom prologues.
+                if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) {
+                    return node;
+                }
+                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                    var variable = _a[_i];
+                    hoistVariableDeclaration(variable.name);
+                }
+                var variables = ts.getInitializedVariables(node.declarationList);
+                if (variables.length === 0) {
+                    return undefined;
+                }
+                return ts.setSourceMapRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
+            }
+        }
+        /**
+         * Visits a binary expression.
+         *
+         * This will be called when one of the following conditions are met:
+         * - The node contains a YieldExpression.
+         *
+         * @param node The node to visit.
+         */
+        function visitBinaryExpression(node) {
+            switch (ts.getExpressionAssociativity(node)) {
+                case 0 /* Left */:
+                    return visitLeftAssociativeBinaryExpression(node);
+                case 1 /* Right */:
+                    return visitRightAssociativeBinaryExpression(node);
+                default:
+                    ts.Debug.fail("Unknown associativity.");
+            }
+        }
+        function isCompoundAssignment(kind) {
+            return kind >= 59 /* FirstCompoundAssignment */
+                && kind <= 70 /* LastCompoundAssignment */;
+        }
+        function getOperatorForCompoundAssignment(kind) {
+            switch (kind) {
+                case 59 /* PlusEqualsToken */: return 37 /* PlusToken */;
+                case 60 /* MinusEqualsToken */: return 38 /* MinusToken */;
+                case 61 /* AsteriskEqualsToken */: return 39 /* AsteriskToken */;
+                case 62 /* AsteriskAsteriskEqualsToken */: return 40 /* AsteriskAsteriskToken */;
+                case 63 /* SlashEqualsToken */: return 41 /* SlashToken */;
+                case 64 /* PercentEqualsToken */: return 42 /* PercentToken */;
+                case 65 /* LessThanLessThanEqualsToken */: return 45 /* LessThanLessThanToken */;
+                case 66 /* GreaterThanGreaterThanEqualsToken */: return 46 /* GreaterThanGreaterThanToken */;
+                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 47 /* GreaterThanGreaterThanGreaterThanToken */;
+                case 68 /* AmpersandEqualsToken */: return 48 /* AmpersandToken */;
+                case 69 /* BarEqualsToken */: return 49 /* BarToken */;
+                case 70 /* CaretEqualsToken */: return 50 /* CaretToken */;
+            }
+        }
+        /**
+         * Visits a right-associative binary expression containing `yield`.
+         *
+         * @param node The node to visit.
+         */
+        function visitRightAssociativeBinaryExpression(node) {
+            var left = node.left, right = node.right;
+            if (containsYield(right)) {
+                var target = void 0;
+                switch (left.kind) {
+                    case 179 /* PropertyAccessExpression */:
+                        // [source]
+                        //      a.b = yield;
+                        //
+                        // [intermediate]
+                        //  .local _a
+                        //      _a = a;
+                        //  .yield resumeLabel
+                        //  .mark resumeLabel
+                        //      _a.b = %sent%;
+                        target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name);
+                        break;
+                    case 180 /* ElementAccessExpression */:
+                        // [source]
+                        //      a[b] = yield;
+                        //
+                        // [intermediate]
+                        //  .local _a, _b
+                        //      _a = a;
+                        //      _b = b;
+                        //  .yield resumeLabel
+                        //  .mark resumeLabel
+                        //      _a[_b] = %sent%;
+                        target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression)));
+                        break;
+                    default:
+                        target = ts.visitNode(left, visitor, ts.isExpression);
+                        break;
+                }
+                var operator = node.operatorToken.kind;
+                if (isCompoundAssignment(operator)) {
+                    return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), getOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node);
+                }
+                else {
+                    return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression));
+                }
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitLeftAssociativeBinaryExpression(node) {
+            if (containsYield(node.right)) {
+                if (ts.isLogicalOperator(node.operatorToken.kind)) {
+                    return visitLogicalBinaryExpression(node);
+                }
+                else if (node.operatorToken.kind === 26 /* CommaToken */) {
+                    return visitCommaExpression(node);
+                }
+                // [source]
+                //      a() + (yield) + c()
+                //
+                // [intermediate]
+                //  .local _a
+                //      _a = a();
+                //  .yield resumeLabel
+                //      _a + %sent% + c()
+                var clone_4 = ts.getMutableClone(node);
+                clone_4.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression));
+                clone_4.right = ts.visitNode(node.right, visitor, ts.isExpression);
+                return clone_4;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a logical binary expression containing `yield`.
+         *
+         * @param node A node to visit.
+         */
+        function visitLogicalBinaryExpression(node) {
+            // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need
+            // to be transformed as such:
+            //
+            // [source]
+            //      x = a() && yield;
+            //
+            // [intermediate]
+            //  .local _a
+            //      _a = a();
+            //  .brfalse resultLabel, (_a)
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      _a = %sent%;
+            //  .mark resultLabel
+            //      x = _a;
+            //
+            // [source]
+            //      x = a() || yield;
+            //
+            // [intermediate]
+            //  .local _a
+            //      _a = a();
+            //  .brtrue resultLabel, (_a)
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      _a = %sent%;
+            //  .mark resultLabel
+            //      x = _a;
+            var resultLabel = defineLabel();
+            var resultLocal = declareLocal();
+            emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left);
+            if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) {
+                // Logical `&&` shortcuts when the left-hand operand is falsey.
+                emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
+            }
+            else {
+                // Logical `||` shortcuts when the left-hand operand is truthy.
+                emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
+            }
+            emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right);
+            markLabel(resultLabel);
+            return resultLocal;
+        }
+        /**
+         * Visits a comma expression containing `yield`.
+         *
+         * @param node The node to visit.
+         */
+        function visitCommaExpression(node) {
+            // [source]
+            //      x = a(), yield, b();
+            //
+            // [intermediate]
+            //      a();
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      x = %sent%, b();
+            var pendingExpressions = [];
+            visit(node.left);
+            visit(node.right);
+            return ts.inlineExpressions(pendingExpressions);
+            function visit(node) {
+                if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) {
+                    visit(node.left);
+                    visit(node.right);
+                }
+                else {
+                    if (containsYield(node) && pendingExpressions.length > 0) {
+                        emitWorker(1 /* Statement */, [ts.createStatement(ts.inlineExpressions(pendingExpressions))]);
+                        pendingExpressions = [];
+                    }
+                    pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression));
+                }
+            }
+        }
+        /**
+         * Visits a conditional expression containing `yield`.
+         *
+         * @param node The node to visit.
+         */
+        function visitConditionalExpression(node) {
+            // [source]
+            //      x = a() ? yield : b();
+            //
+            // [intermediate]
+            //  .local _a
+            //  .brfalse whenFalseLabel, (a())
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      _a = %sent%;
+            //  .br resultLabel
+            //  .mark whenFalseLabel
+            //      _a = b();
+            //  .mark resultLabel
+            //      x = _a;
+            // We only need to perform a specific transformation if a `yield` expression exists
+            // in either the `whenTrue` or `whenFalse` branches.
+            // A `yield` in the condition will be handled by the normal visitor.
+            if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
+                var whenFalseLabel = defineLabel();
+                var resultLabel = defineLabel();
+                var resultLocal = declareLocal();
+                emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition);
+                emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue);
+                emitBreak(resultLabel);
+                markLabel(whenFalseLabel);
+                emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse);
+                markLabel(resultLabel);
+                return resultLocal;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        /**
+         * Visits a `yield` expression.
+         *
+         * @param node The node to visit.
+         */
+        function visitYieldExpression(node) {
+            // [source]
+            //      x = yield a();
+            //
+            // [intermediate]
+            //  .yield resumeLabel, (a())
+            //  .mark resumeLabel
+            //      x = %sent%;
+            var resumeLabel = defineLabel();
+            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
+            if (node.asteriskToken) {
+                var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0
+                    ? ts.createValuesHelper(context, expression, /*location*/ node)
+                    : expression;
+                emitYieldStar(iterator, /*location*/ node);
+            }
+            else {
+                emitYield(expression, /*location*/ node);
+            }
+            markLabel(resumeLabel);
+            return createGeneratorResume(/*location*/ node);
+        }
+        /**
+         * Visits an ArrayLiteralExpression that contains a YieldExpression.
+         *
+         * @param node The node to visit.
+         */
+        function visitArrayLiteralExpression(node) {
+            return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
+        }
+        /**
+         * Visits an array of expressions containing one or more YieldExpression nodes
+         * and returns an expression for the resulting value.
+         *
+         * @param elements The elements to visit.
+         * @param multiLine Whether array literals created should be emitted on multiple lines.
+         */
+        function visitElements(elements, leadingElement, location, multiLine) {
+            // [source]
+            //      ar = [1, yield, 2];
+            //
+            // [intermediate]
+            //  .local _a
+            //      _a = [1];
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      ar = _a.concat([%sent%, 2]);
+            var numInitialElements = countInitialNodesWithoutYield(elements);
+            var temp;
+            if (numInitialElements > 0) {
+                temp = declareLocal();
+                var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements);
+                emitAssignment(temp, ts.createArrayLiteral(leadingElement
+                    ? [leadingElement].concat(initialElements) : initialElements));
+                leadingElement = undefined;
+            }
+            var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements);
+            return temp
+                ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
+                : ts.setTextRange(ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine), location);
+            function reduceElement(expressions, element) {
+                if (containsYield(element) && expressions.length > 0) {
+                    var hasAssignedTemp = temp !== undefined;
+                    if (!temp) {
+                        temp = declareLocal();
+                    }
+                    emitAssignment(temp, hasAssignedTemp
+                        ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
+                        : ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine));
+                    leadingElement = undefined;
+                    expressions = [];
+                }
+                expressions.push(ts.visitNode(element, visitor, ts.isExpression));
+                return expressions;
+            }
+        }
+        function visitObjectLiteralExpression(node) {
+            // [source]
+            //      o = {
+            //          a: 1,
+            //          b: yield,
+            //          c: 2
+            //      };
+            //
+            // [intermediate]
+            //  .local _a
+            //      _a = {
+            //          a: 1
+            //      };
+            //  .yield resumeLabel
+            //  .mark resumeLabel
+            //      o = (_a.b = %sent%,
+            //          _a.c = 2,
+            //          _a);
+            var properties = node.properties;
+            var multiLine = node.multiLine;
+            var numInitialProperties = countInitialNodesWithoutYield(properties);
+            var temp = declareLocal();
+            emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine));
+            var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties);
+            expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
+            return ts.inlineExpressions(expressions);
+            function reduceProperty(expressions, property) {
+                if (containsYield(property) && expressions.length > 0) {
+                    emitStatement(ts.createStatement(ts.inlineExpressions(expressions)));
+                    expressions = [];
+                }
+                var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp);
+                var visited = ts.visitNode(expression, visitor, ts.isExpression);
+                if (visited) {
+                    if (multiLine) {
+                        visited.startsOnNewLine = true;
+                    }
+                    expressions.push(visited);
+                }
+                return expressions;
+            }
+        }
+        /**
+         * Visits an ElementAccessExpression that contains a YieldExpression.
+         *
+         * @param node The node to visit.
+         */
+        function visitElementAccessExpression(node) {
+            if (containsYield(node.argumentExpression)) {
+                // [source]
+                //      a = x[yield];
+                //
+                // [intermediate]
+                //  .local _a
+                //      _a = x;
+                //  .yield resumeLabel
+                //  .mark resumeLabel
+                //      a = _a[%sent%]
+                var clone_5 = ts.getMutableClone(node);
+                clone_5.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
+                clone_5.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression);
+                return clone_5;
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitCallExpression(node) {
+            if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) {
+                // [source]
+                //      a.b(1, yield, 2);
+                //
+                // [intermediate]
+                //  .local _a, _b, _c
+                //      _b = (_a = a).b;
+                //      _c = [1];
+                //  .yield resumeLabel
+                //  .mark resumeLabel
+                //      _b.apply(_a, _c.concat([%sent%, 2]));
+                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg;
+                return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), 
+                /*location*/ node), node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function visitNewExpression(node) {
+            if (ts.forEach(node.arguments, containsYield)) {
+                // [source]
+                //      new a.b(1, yield, 2);
+                //
+                // [intermediate]
+                //  .local _a, _b, _c
+                //      _b = (_a = a.b).bind;
+                //      _c = [1];
+                //  .yield resumeLabel
+                //  .mark resumeLabel
+                //      new (_b.apply(_a, _c.concat([%sent%, 2])));
+                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
+                return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, 
+                /*leadingElement*/ ts.createVoidZero())), 
+                /*typeArguments*/ undefined, []), node), node);
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function transformAndEmitStatements(statements, start) {
+            if (start === void 0) { start = 0; }
+            var numStatements = statements.length;
+            for (var i = start; i < numStatements; i++) {
+                transformAndEmitStatement(statements[i]);
+            }
+        }
+        function transformAndEmitEmbeddedStatement(node) {
+            if (ts.isBlock(node)) {
+                transformAndEmitStatements(node.statements);
+            }
+            else {
+                transformAndEmitStatement(node);
+            }
+        }
+        function transformAndEmitStatement(node) {
+            var savedInStatementContainingYield = inStatementContainingYield;
+            if (!inStatementContainingYield) {
+                inStatementContainingYield = containsYield(node);
+            }
+            transformAndEmitStatementWorker(node);
+            inStatementContainingYield = savedInStatementContainingYield;
+        }
+        function transformAndEmitStatementWorker(node) {
+            switch (node.kind) {
+                case 207 /* Block */:
+                    return transformAndEmitBlock(node);
+                case 210 /* ExpressionStatement */:
+                    return transformAndEmitExpressionStatement(node);
+                case 211 /* IfStatement */:
+                    return transformAndEmitIfStatement(node);
+                case 212 /* DoStatement */:
+                    return transformAndEmitDoStatement(node);
+                case 213 /* WhileStatement */:
+                    return transformAndEmitWhileStatement(node);
+                case 214 /* ForStatement */:
+                    return transformAndEmitForStatement(node);
+                case 215 /* ForInStatement */:
+                    return transformAndEmitForInStatement(node);
+                case 217 /* ContinueStatement */:
+                    return transformAndEmitContinueStatement(node);
+                case 218 /* BreakStatement */:
+                    return transformAndEmitBreakStatement(node);
+                case 219 /* ReturnStatement */:
+                    return transformAndEmitReturnStatement(node);
+                case 220 /* WithStatement */:
+                    return transformAndEmitWithStatement(node);
+                case 221 /* SwitchStatement */:
+                    return transformAndEmitSwitchStatement(node);
+                case 222 /* LabeledStatement */:
+                    return transformAndEmitLabeledStatement(node);
+                case 223 /* ThrowStatement */:
+                    return transformAndEmitThrowStatement(node);
+                case 224 /* TryStatement */:
+                    return transformAndEmitTryStatement(node);
+                default:
+                    return emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function transformAndEmitBlock(node) {
+            if (containsYield(node)) {
+                transformAndEmitStatements(node.statements);
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function transformAndEmitExpressionStatement(node) {
+            emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+        }
+        function transformAndEmitVariableDeclarationList(node) {
+            for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
+                var variable = _a[_i];
+                var name = ts.getSynthesizedClone(variable.name);
+                ts.setCommentRange(name, variable.name);
+                hoistVariableDeclaration(name);
+            }
+            var variables = ts.getInitializedVariables(node);
+            var numVariables = variables.length;
+            var variablesWritten = 0;
+            var pendingExpressions = [];
+            while (variablesWritten < numVariables) {
+                for (var i = variablesWritten; i < numVariables; i++) {
+                    var variable = variables[i];
+                    if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
+                        break;
+                    }
+                    pendingExpressions.push(transformInitializedVariable(variable));
+                }
+                if (pendingExpressions.length) {
+                    emitStatement(ts.createStatement(ts.inlineExpressions(pendingExpressions)));
+                    variablesWritten += pendingExpressions.length;
+                    pendingExpressions = [];
+                }
+            }
+            return undefined;
+        }
+        function transformInitializedVariable(node) {
+            return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node);
+        }
+        function transformAndEmitIfStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      if (x)
+                //          /*thenStatement*/
+                //      else
+                //          /*elseStatement*/
+                //
+                // [intermediate]
+                //  .brfalse elseLabel, (x)
+                //      /*thenStatement*/
+                //  .br endLabel
+                //  .mark elseLabel
+                //      /*elseStatement*/
+                //  .mark endLabel
+                if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
+                    var endLabel = defineLabel();
+                    var elseLabel = node.elseStatement ? defineLabel() : undefined;
+                    emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression);
+                    transformAndEmitEmbeddedStatement(node.thenStatement);
+                    if (node.elseStatement) {
+                        emitBreak(endLabel);
+                        markLabel(elseLabel);
+                        transformAndEmitEmbeddedStatement(node.elseStatement);
+                    }
+                    markLabel(endLabel);
+                }
+                else {
+                    emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+                }
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function transformAndEmitDoStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      do {
+                //          /*body*/
+                //      }
+                //      while (i < 10);
+                //
+                // [intermediate]
+                //  .loop conditionLabel, endLabel
+                //  .mark loopLabel
+                //      /*body*/
+                //  .mark conditionLabel
+                //  .brtrue loopLabel, (i < 10)
+                //  .endloop
+                //  .mark endLabel
+                var conditionLabel = defineLabel();
+                var loopLabel = defineLabel();
+                beginLoopBlock(/*continueLabel*/ conditionLabel);
+                markLabel(loopLabel);
+                transformAndEmitEmbeddedStatement(node.statement);
+                markLabel(conditionLabel);
+                emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
+                endLoopBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitDoStatement(node) {
+            if (inStatementContainingYield) {
+                beginScriptLoopBlock();
+                node = ts.visitEachChild(node, visitor, context);
+                endLoopBlock();
+                return node;
+            }
+            else {
+                return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function transformAndEmitWhileStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      while (i < 10) {
+                //          /*body*/
+                //      }
+                //
+                // [intermediate]
+                //  .loop loopLabel, endLabel
+                //  .mark loopLabel
+                //  .brfalse endLabel, (i < 10)
+                //      /*body*/
+                //  .br loopLabel
+                //  .endloop
+                //  .mark endLabel
+                var loopLabel = defineLabel();
+                var endLabel = beginLoopBlock(loopLabel);
+                markLabel(loopLabel);
+                emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
+                transformAndEmitEmbeddedStatement(node.statement);
+                emitBreak(loopLabel);
+                endLoopBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitWhileStatement(node) {
+            if (inStatementContainingYield) {
+                beginScriptLoopBlock();
+                node = ts.visitEachChild(node, visitor, context);
+                endLoopBlock();
+                return node;
+            }
+            else {
+                return ts.visitEachChild(node, visitor, context);
+            }
+        }
+        function transformAndEmitForStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      for (var i = 0; i < 10; i++) {
+                //          /*body*/
+                //      }
+                //
+                // [intermediate]
+                //  .local i
+                //      i = 0;
+                //  .loop incrementLabel, endLoopLabel
+                //  .mark conditionLabel
+                //  .brfalse endLoopLabel, (i < 10)
+                //      /*body*/
+                //  .mark incrementLabel
+                //      i++;
+                //  .br conditionLabel
+                //  .endloop
+                //  .mark endLoopLabel
+                var conditionLabel = defineLabel();
+                var incrementLabel = defineLabel();
+                var endLabel = beginLoopBlock(incrementLabel);
+                if (node.initializer) {
+                    var initializer = node.initializer;
+                    if (ts.isVariableDeclarationList(initializer)) {
+                        transformAndEmitVariableDeclarationList(initializer);
+                    }
+                    else {
+                        emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer));
+                    }
+                }
+                markLabel(conditionLabel);
+                if (node.condition) {
+                    emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression));
+                }
+                transformAndEmitEmbeddedStatement(node.statement);
+                markLabel(incrementLabel);
+                if (node.incrementor) {
+                    emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor));
+                }
+                emitBreak(conditionLabel);
+                endLoopBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitForStatement(node) {
+            if (inStatementContainingYield) {
+                beginScriptLoopBlock();
+            }
+            var initializer = node.initializer;
+            if (initializer && ts.isVariableDeclarationList(initializer)) {
+                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
+                    var variable = _a[_i];
+                    hoistVariableDeclaration(variable.name);
+                }
+                var variables = ts.getInitializedVariables(initializer);
+                node = ts.updateFor(node, variables.length > 0
+                    ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable))
+                    : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            }
+            else {
+                node = ts.visitEachChild(node, visitor, context);
+            }
+            if (inStatementContainingYield) {
+                endLoopBlock();
+            }
+            return node;
+        }
+        function transformAndEmitForInStatement(node) {
+            // TODO(rbuckton): Source map locations
+            if (containsYield(node)) {
+                // [source]
+                //      for (var p in o) {
+                //          /*body*/
+                //      }
+                //
+                // [intermediate]
+                //  .local _a, _b, _i
+                //      _a = [];
+                //      for (_b in o) _a.push(_b);
+                //      _i = 0;
+                //  .loop incrementLabel, endLoopLabel
+                //  .mark conditionLabel
+                //  .brfalse endLoopLabel, (_i < _a.length)
+                //      p = _a[_i];
+                //      /*body*/
+                //  .mark incrementLabel
+                //      _b++;
+                //  .br conditionLabel
+                //  .endloop
+                //  .mark endLoopLabel
+                var keysArray = declareLocal(); // _a
+                var key = declareLocal(); // _b
+                var keysIndex = ts.createLoopVariable(); // _i
+                var initializer = node.initializer;
+                hoistVariableDeclaration(keysIndex);
+                emitAssignment(keysArray, ts.createArrayLiteral());
+                emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), 
+                /*typeArguments*/ undefined, [key]))));
+                emitAssignment(keysIndex, ts.createLiteral(0));
+                var conditionLabel = defineLabel();
+                var incrementLabel = defineLabel();
+                var endLabel = beginLoopBlock(incrementLabel);
+                markLabel(conditionLabel);
+                emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length")));
+                var variable = void 0;
+                if (ts.isVariableDeclarationList(initializer)) {
+                    for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
+                        var variable_1 = _a[_i];
+                        hoistVariableDeclaration(variable_1.name);
+                    }
+                    variable = ts.getSynthesizedClone(initializer.declarations[0].name);
+                }
+                else {
+                    variable = ts.visitNode(initializer, visitor, ts.isExpression);
+                    ts.Debug.assert(ts.isLeftHandSideExpression(variable));
+                }
+                emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex));
+                transformAndEmitEmbeddedStatement(node.statement);
+                markLabel(incrementLabel);
+                emitStatement(ts.createStatement(ts.createPostfixIncrement(keysIndex)));
+                emitBreak(conditionLabel);
+                endLoopBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitForInStatement(node) {
+            // [source]
+            //      for (var x in a) {
+            //          /*body*/
+            //      }
+            //
+            // [intermediate]
+            //  .local x
+            //  .loop
+            //      for (x in a) {
+            //          /*body*/
+            //      }
+            //  .endloop
+            if (inStatementContainingYield) {
+                beginScriptLoopBlock();
+            }
+            var initializer = node.initializer;
+            if (ts.isVariableDeclarationList(initializer)) {
+                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
+                    var variable = _a[_i];
+                    hoistVariableDeclaration(variable.name);
+                }
+                node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
+            }
+            else {
+                node = ts.visitEachChild(node, visitor, context);
+            }
+            if (inStatementContainingYield) {
+                endLoopBlock();
+            }
+            return node;
+        }
+        function transformAndEmitContinueStatement(node) {
+            var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined);
+            if (label > 0) {
+                emitBreak(label, /*location*/ node);
+            }
+            else {
+                // invalid continue without a containing loop. Leave the node as is, per #17875.
+                emitStatement(node);
+            }
+        }
+        function visitContinueStatement(node) {
+            if (inStatementContainingYield) {
+                var label = findContinueTarget(node.label && ts.idText(node.label));
+                if (label > 0) {
+                    return createInlineBreak(label, /*location*/ node);
+                }
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function transformAndEmitBreakStatement(node) {
+            var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined);
+            if (label > 0) {
+                emitBreak(label, /*location*/ node);
+            }
+            else {
+                // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
+                emitStatement(node);
+            }
+        }
+        function visitBreakStatement(node) {
+            if (inStatementContainingYield) {
+                var label = findBreakTarget(node.label && ts.idText(node.label));
+                if (label > 0) {
+                    return createInlineBreak(label, /*location*/ node);
+                }
+            }
+            return ts.visitEachChild(node, visitor, context);
+        }
+        function transformAndEmitReturnStatement(node) {
+            emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
+            /*location*/ node);
+        }
+        function visitReturnStatement(node) {
+            return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
+            /*location*/ node);
+        }
+        function transformAndEmitWithStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      with (x) {
+                //          /*body*/
+                //      }
+                //
+                // [intermediate]
+                //  .with (x)
+                //      /*body*/
+                //  .endwith
+                beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)));
+                transformAndEmitEmbeddedStatement(node.statement);
+                endWithBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function transformAndEmitSwitchStatement(node) {
+            if (containsYield(node.caseBlock)) {
+                // [source]
+                //      switch (x) {
+                //          case a:
+                //              /*caseStatements*/
+                //          case b:
+                //              /*caseStatements*/
+                //          default:
+                //              /*defaultStatements*/
+                //      }
+                //
+                // [intermediate]
+                //  .local _a
+                //  .switch endLabel
+                //      _a = x;
+                //      switch (_a) {
+                //          case a:
+                //  .br clauseLabels[0]
+                //      }
+                //      switch (_a) {
+                //          case b:
+                //  .br clauseLabels[1]
+                //      }
+                //  .br clauseLabels[2]
+                //  .mark clauseLabels[0]
+                //      /*caseStatements*/
+                //  .mark clauseLabels[1]
+                //      /*caseStatements*/
+                //  .mark clauseLabels[2]
+                //      /*caseStatements*/
+                //  .endswitch
+                //  .mark endLabel
+                var caseBlock = node.caseBlock;
+                var numClauses = caseBlock.clauses.length;
+                var endLabel = beginSwitchBlock();
+                var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression));
+                // Create labels for each clause and find the index of the first default clause.
+                var clauseLabels = [];
+                var defaultClauseIndex = -1;
+                for (var i = 0; i < numClauses; i++) {
+                    var clause = caseBlock.clauses[i];
+                    clauseLabels.push(defineLabel());
+                    if (clause.kind === 258 /* DefaultClause */ && defaultClauseIndex === -1) {
+                        defaultClauseIndex = i;
+                    }
+                }
+                // Emit switch statements for each run of case clauses either from the first case
+                // clause or the next case clause with a `yield` in its expression, up to the next
+                // case clause with a `yield` in its expression.
+                var clausesWritten = 0;
+                var pendingClauses = [];
+                while (clausesWritten < numClauses) {
+                    var defaultClausesSkipped = 0;
+                    for (var i = clausesWritten; i < numClauses; i++) {
+                        var clause = caseBlock.clauses[i];
+                        if (clause.kind === 257 /* CaseClause */) {
+                            var caseClause = clause;
+                            if (containsYield(caseClause.expression) && pendingClauses.length > 0) {
+                                break;
+                            }
+                            pendingClauses.push(ts.createCaseClause(ts.visitNode(caseClause.expression, visitor, ts.isExpression), [
+                                createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression)
+                            ]));
+                        }
+                        else {
+                            defaultClausesSkipped++;
+                        }
+                    }
+                    if (pendingClauses.length) {
+                        emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses)));
+                        clausesWritten += pendingClauses.length;
+                        pendingClauses = [];
+                    }
+                    if (defaultClausesSkipped > 0) {
+                        clausesWritten += defaultClausesSkipped;
+                        defaultClausesSkipped = 0;
+                    }
+                }
+                if (defaultClauseIndex >= 0) {
+                    emitBreak(clauseLabels[defaultClauseIndex]);
+                }
+                else {
+                    emitBreak(endLabel);
+                }
+                for (var i = 0; i < numClauses; i++) {
+                    markLabel(clauseLabels[i]);
+                    transformAndEmitStatements(caseBlock.clauses[i].statements);
+                }
+                endSwitchBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitSwitchStatement(node) {
+            if (inStatementContainingYield) {
+                beginScriptSwitchBlock();
+            }
+            node = ts.visitEachChild(node, visitor, context);
+            if (inStatementContainingYield) {
+                endSwitchBlock();
+            }
+            return node;
+        }
+        function transformAndEmitLabeledStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      x: {
+                //          /*body*/
+                //      }
+                //
+                // [intermediate]
+                //  .labeled "x", endLabel
+                //      /*body*/
+                //  .endlabeled
+                //  .mark endLabel
+                beginLabeledBlock(ts.idText(node.label));
+                transformAndEmitEmbeddedStatement(node.statement);
+                endLabeledBlock();
+            }
+            else {
+                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
+            }
+        }
+        function visitLabeledStatement(node) {
+            if (inStatementContainingYield) {
+                beginScriptLabeledBlock(ts.idText(node.label));
+            }
+            node = ts.visitEachChild(node, visitor, context);
+            if (inStatementContainingYield) {
+                endLabeledBlock();
+            }
+            return node;
+        }
+        function transformAndEmitThrowStatement(node) {
+            emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), 
+            /*location*/ node);
+        }
+        function transformAndEmitTryStatement(node) {
+            if (containsYield(node)) {
+                // [source]
+                //      try {
+                //          /*tryBlock*/
+                //      }
+                //      catch (e) {
+                //          /*catchBlock*/
+                //      }
+                //      finally {
+                //          /*finallyBlock*/
+                //      }
+                //
+                // [intermediate]
+                //  .local _a
+                //  .try tryLabel, catchLabel, finallyLabel, endLabel
+                //  .mark tryLabel
+                //  .nop
+                //      /*tryBlock*/
+                //  .br endLabel
+                //  .catch
+                //  .mark catchLabel
+                //      _a = %error%;
+                //      /*catchBlock*/
+                //  .br endLabel
+                //  .finally
+                //  .mark finallyLabel
+                //      /*finallyBlock*/
+                //  .endfinally
+                //  .endtry
+                //  .mark endLabel
+                beginExceptionBlock();
+                transformAndEmitEmbeddedStatement(node.tryBlock);
+                if (node.catchClause) {
+                    beginCatchBlock(node.catchClause.variableDeclaration);
+                    transformAndEmitEmbeddedStatement(node.catchClause.block);
+                }
+                if (node.finallyBlock) {
+                    beginFinallyBlock();
+                    transformAndEmitEmbeddedStatement(node.finallyBlock);
+                }
+                endExceptionBlock();
+            }
+            else {
+                emitStatement(ts.visitEachChild(node, visitor, context));
+            }
+        }
+        function containsYield(node) {
+            return node && (node.transformFlags & 16777216 /* ContainsYield */) !== 0;
+        }
+        function countInitialNodesWithoutYield(nodes) {
+            var numNodes = nodes.length;
+            for (var i = 0; i < numNodes; i++) {
+                if (containsYield(nodes[i])) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (hint === 1 /* Expression */) {
+                return substituteExpression(node);
+            }
+            return node;
+        }
+        function substituteExpression(node) {
+            if (ts.isIdentifier(node)) {
+                return substituteExpressionIdentifier(node);
+            }
+            return node;
+        }
+        function substituteExpressionIdentifier(node) {
+            if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) {
+                var original = ts.getOriginalNode(node);
+                if (ts.isIdentifier(original) && original.parent) {
+                    var declaration = resolver.getReferencedValueDeclaration(original);
+                    if (declaration) {
+                        var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)];
+                        if (name) {
+                            var clone_6 = ts.getMutableClone(name);
+                            ts.setSourceMapRange(clone_6, node);
+                            ts.setCommentRange(clone_6, node);
+                            return clone_6;
+                        }
+                    }
+                }
+            }
+            return node;
+        }
+        function cacheExpression(node) {
+            var temp;
+            if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) {
+                return node;
+            }
+            temp = ts.createTempVariable(hoistVariableDeclaration);
+            emitAssignment(temp, node, /*location*/ node);
+            return temp;
+        }
+        function declareLocal(name) {
+            var temp = name
+                ? ts.createUniqueName(name)
+                : ts.createTempVariable(/*recordTempVariable*/ undefined);
+            hoistVariableDeclaration(temp);
+            return temp;
+        }
+        /**
+         * Defines a label, uses as the target of a Break operation.
+         */
+        function defineLabel() {
+            if (!labelOffsets) {
+                labelOffsets = [];
+            }
+            var label = nextLabelId;
+            nextLabelId++;
+            labelOffsets[label] = -1;
+            return label;
+        }
+        /**
+         * Marks the current operation with the specified label.
+         */
+        function markLabel(label) {
+            ts.Debug.assert(labelOffsets !== undefined, "No labels were defined.");
+            labelOffsets[label] = operations ? operations.length : 0;
+        }
+        /**
+         * Begins a block operation (With, Break/Continue, Try/Catch/Finally)
+         *
+         * @param block Information about the block.
+         */
+        function beginBlock(block) {
+            if (!blocks) {
+                blocks = [];
+                blockActions = [];
+                blockOffsets = [];
+                blockStack = [];
+            }
+            var index = blockActions.length;
+            blockActions[index] = 0 /* Open */;
+            blockOffsets[index] = operations ? operations.length : 0;
+            blocks[index] = block;
+            blockStack.push(block);
+            return index;
+        }
+        /**
+         * Ends the current block operation.
+         */
+        function endBlock() {
+            var block = peekBlock();
+            ts.Debug.assert(block !== undefined, "beginBlock was never called.");
+            var index = blockActions.length;
+            blockActions[index] = 1 /* Close */;
+            blockOffsets[index] = operations ? operations.length : 0;
+            blocks[index] = block;
+            blockStack.pop();
+            return block;
+        }
+        /**
+         * Gets the current open block.
+         */
+        function peekBlock() {
+            return ts.lastOrUndefined(blockStack);
+        }
+        /**
+         * Gets the kind of the current open block.
+         */
+        function peekBlockKind() {
+            var block = peekBlock();
+            return block && block.kind;
+        }
+        /**
+         * Begins a code block for a generated `with` statement.
+         *
+         * @param expression An identifier representing expression for the `with` block.
+         */
+        function beginWithBlock(expression) {
+            var startLabel = defineLabel();
+            var endLabel = defineLabel();
+            markLabel(startLabel);
+            beginBlock({
+                kind: 1 /* With */,
+                expression: expression,
+                startLabel: startLabel,
+                endLabel: endLabel
+            });
+        }
+        /**
+         * Ends a code block for a generated `with` statement.
+         */
+        function endWithBlock() {
+            ts.Debug.assert(peekBlockKind() === 1 /* With */);
+            var block = endBlock();
+            markLabel(block.endLabel);
+        }
+        /**
+         * Begins a code block for a generated `try` statement.
+         */
+        function beginExceptionBlock() {
+            var startLabel = defineLabel();
+            var endLabel = defineLabel();
+            markLabel(startLabel);
+            beginBlock({
+                kind: 0 /* Exception */,
+                state: 0 /* Try */,
+                startLabel: startLabel,
+                endLabel: endLabel
+            });
+            emitNop();
+            return endLabel;
+        }
+        /**
+         * Enters the `catch` clause of a generated `try` statement.
+         *
+         * @param variable The catch variable.
+         */
+        function beginCatchBlock(variable) {
+            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
+            // generated identifiers should already be unique within a file
+            var name;
+            if (ts.isGeneratedIdentifier(variable.name)) {
+                name = variable.name;
+                hoistVariableDeclaration(variable.name);
+            }
+            else {
+                var text = ts.idText(variable.name);
+                name = declareLocal(text);
+                if (!renamedCatchVariables) {
+                    renamedCatchVariables = ts.createMap();
+                    renamedCatchVariableDeclarations = [];
+                    context.enableSubstitution(71 /* Identifier */);
+                }
+                renamedCatchVariables.set(text, true);
+                renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name;
+            }
+            var exception = peekBlock();
+            ts.Debug.assert(exception.state < 1 /* Catch */);
+            var endLabel = exception.endLabel;
+            emitBreak(endLabel);
+            var catchLabel = defineLabel();
+            markLabel(catchLabel);
+            exception.state = 1 /* Catch */;
+            exception.catchVariable = name;
+            exception.catchLabel = catchLabel;
+            emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []));
+            emitNop();
+        }
+        /**
+         * Enters the `finally` block of a generated `try` statement.
+         */
+        function beginFinallyBlock() {
+            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
+            var exception = peekBlock();
+            ts.Debug.assert(exception.state < 2 /* Finally */);
+            var endLabel = exception.endLabel;
+            emitBreak(endLabel);
+            var finallyLabel = defineLabel();
+            markLabel(finallyLabel);
+            exception.state = 2 /* Finally */;
+            exception.finallyLabel = finallyLabel;
+        }
+        /**
+         * Ends the code block for a generated `try` statement.
+         */
+        function endExceptionBlock() {
+            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
+            var exception = endBlock();
+            var state = exception.state;
+            if (state < 2 /* Finally */) {
+                emitBreak(exception.endLabel);
+            }
+            else {
+                emitEndfinally();
+            }
+            markLabel(exception.endLabel);
+            emitNop();
+            exception.state = 3 /* Done */;
+        }
+        /**
+         * Begins a code block that supports `break` or `continue` statements that are defined in
+         * the source tree and not from generated code.
+         *
+         * @param labelText Names from containing labeled statements.
+         */
+        function beginScriptLoopBlock() {
+            beginBlock({
+                kind: 3 /* Loop */,
+                isScript: true,
+                breakLabel: -1,
+                continueLabel: -1
+            });
+        }
+        /**
+         * Begins a code block that supports `break` or `continue` statements that are defined in
+         * generated code. Returns a label used to mark the operation to which to jump when a
+         * `break` statement targets this block.
+         *
+         * @param continueLabel A Label used to mark the operation to which to jump when a
+         *                      `continue` statement targets this block.
+         */
+        function beginLoopBlock(continueLabel) {
+            var breakLabel = defineLabel();
+            beginBlock({
+                kind: 3 /* Loop */,
+                isScript: false,
+                breakLabel: breakLabel,
+                continueLabel: continueLabel,
+            });
+            return breakLabel;
+        }
+        /**
+         * Ends a code block that supports `break` or `continue` statements that are defined in
+         * generated code or in the source tree.
+         */
+        function endLoopBlock() {
+            ts.Debug.assert(peekBlockKind() === 3 /* Loop */);
+            var block = endBlock();
+            var breakLabel = block.breakLabel;
+            if (!block.isScript) {
+                markLabel(breakLabel);
+            }
+        }
+        /**
+         * Begins a code block that supports `break` statements that are defined in the source
+         * tree and not from generated code.
+         *
+         */
+        function beginScriptSwitchBlock() {
+            beginBlock({
+                kind: 2 /* Switch */,
+                isScript: true,
+                breakLabel: -1
+            });
+        }
+        /**
+         * Begins a code block that supports `break` statements that are defined in generated code.
+         * Returns a label used to mark the operation to which to jump when a `break` statement
+         * targets this block.
+         */
+        function beginSwitchBlock() {
+            var breakLabel = defineLabel();
+            beginBlock({
+                kind: 2 /* Switch */,
+                isScript: false,
+                breakLabel: breakLabel,
+            });
+            return breakLabel;
+        }
+        /**
+         * Ends a code block that supports `break` statements that are defined in generated code.
+         */
+        function endSwitchBlock() {
+            ts.Debug.assert(peekBlockKind() === 2 /* Switch */);
+            var block = endBlock();
+            var breakLabel = block.breakLabel;
+            if (!block.isScript) {
+                markLabel(breakLabel);
+            }
+        }
+        function beginScriptLabeledBlock(labelText) {
+            beginBlock({
+                kind: 4 /* Labeled */,
+                isScript: true,
+                labelText: labelText,
+                breakLabel: -1
+            });
+        }
+        function beginLabeledBlock(labelText) {
+            var breakLabel = defineLabel();
+            beginBlock({
+                kind: 4 /* Labeled */,
+                isScript: false,
+                labelText: labelText,
+                breakLabel: breakLabel
+            });
+        }
+        function endLabeledBlock() {
+            ts.Debug.assert(peekBlockKind() === 4 /* Labeled */);
+            var block = endBlock();
+            if (!block.isScript) {
+                markLabel(block.breakLabel);
+            }
+        }
+        /**
+         * Indicates whether the provided block supports `break` statements.
+         *
+         * @param block A code block.
+         */
+        function supportsUnlabeledBreak(block) {
+            return block.kind === 2 /* Switch */
+                || block.kind === 3 /* Loop */;
+        }
+        /**
+         * Indicates whether the provided block supports `break` statements with labels.
+         *
+         * @param block A code block.
+         */
+        function supportsLabeledBreakOrContinue(block) {
+            return block.kind === 4 /* Labeled */;
+        }
+        /**
+         * Indicates whether the provided block supports `continue` statements.
+         *
+         * @param block A code block.
+         */
+        function supportsUnlabeledContinue(block) {
+            return block.kind === 3 /* Loop */;
+        }
+        function hasImmediateContainingLabeledBlock(labelText, start) {
+            for (var j = start; j >= 0; j--) {
+                var containingBlock = blockStack[j];
+                if (supportsLabeledBreakOrContinue(containingBlock)) {
+                    if (containingBlock.labelText === labelText) {
+                        return true;
+                    }
+                }
+                else {
+                    break;
+                }
+            }
+            return false;
+        }
+        /**
+         * Finds the label that is the target for a `break` statement.
+         *
+         * @param labelText An optional name of a containing labeled statement.
+         */
+        function findBreakTarget(labelText) {
+            if (blockStack) {
+                if (labelText) {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
+                            return block.breakLabel;
+                        }
+                        else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
+                            return block.breakLabel;
+                        }
+                    }
+                }
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
+                    }
+                }
+            }
+            return 0;
+        }
+        /**
+         * Finds the label that is the target for a `continue` statement.
+         *
+         * @param labelText An optional name of a containing labeled statement.
+         */
+        function findContinueTarget(labelText) {
+            if (blockStack) {
+                if (labelText) {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
+                            return block.continueLabel;
+                        }
+                    }
+                }
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
+                    }
+                }
+            }
+            return 0;
+        }
+        /**
+         * Creates an expression that can be used to indicate the value for a label.
+         *
+         * @param label A label.
+         */
+        function createLabel(label) {
+            if (label > 0) {
+                if (labelExpressions === undefined) {
+                    labelExpressions = [];
+                }
+                var expression = ts.createLiteral(-1);
+                if (labelExpressions[label] === undefined) {
+                    labelExpressions[label] = [expression];
+                }
+                else {
+                    labelExpressions[label].push(expression);
+                }
+                return expression;
+            }
+            return ts.createOmittedExpression();
+        }
+        /**
+         * Creates a numeric literal for the provided instruction.
+         */
+        function createInstruction(instruction) {
+            var literal = ts.createLiteral(instruction);
+            ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
+            return literal;
+        }
+        /**
+         * Creates a statement that can be used indicate a Break operation to the provided label.
+         *
+         * @param label A label.
+         * @param location An optional source map location for the statement.
+         */
+        function createInlineBreak(label, location) {
+            ts.Debug.assertLessThan(0, label, "Invalid label");
+            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(3 /* Break */),
+                createLabel(label)
+            ])), location);
+        }
+        /**
+         * Creates a statement that can be used indicate a Return operation.
+         *
+         * @param expression The expression for the return statement.
+         * @param location An optional source map location for the statement.
+         */
+        function createInlineReturn(expression, location) {
+            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
+                ? [createInstruction(2 /* Return */), expression]
+                : [createInstruction(2 /* Return */)])), location);
+        }
+        /**
+         * Creates an expression that can be used to resume from a Yield operation.
+         */
+        function createGeneratorResume(location) {
+            return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), 
+            /*typeArguments*/ undefined, []), location);
+        }
+        /**
+         * Emits an empty instruction.
+         */
+        function emitNop() {
+            emitWorker(0 /* Nop */);
+        }
+        /**
+         * Emits a Statement.
+         *
+         * @param node A statement.
+         */
+        function emitStatement(node) {
+            if (node) {
+                emitWorker(1 /* Statement */, [node]);
+            }
+            else {
+                emitNop();
+            }
+        }
+        /**
+         * Emits an Assignment operation.
+         *
+         * @param left The left-hand side of the assignment.
+         * @param right The right-hand side of the assignment.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitAssignment(left, right, location) {
+            emitWorker(2 /* Assign */, [left, right], location);
+        }
+        /**
+         * Emits a Break operation to the specified label.
+         *
+         * @param label A label.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitBreak(label, location) {
+            emitWorker(3 /* Break */, [label], location);
+        }
+        /**
+         * Emits a Break operation to the specified label when a condition evaluates to a truthy
+         * value at runtime.
+         *
+         * @param label A label.
+         * @param condition The condition.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitBreakWhenTrue(label, condition, location) {
+            emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
+        }
+        /**
+         * Emits a Break to the specified label when a condition evaluates to a falsey value at
+         * runtime.
+         *
+         * @param label A label.
+         * @param condition The condition.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitBreakWhenFalse(label, condition, location) {
+            emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
+        }
+        /**
+         * Emits a YieldStar operation for the provided expression.
+         *
+         * @param expression An optional value for the yield operation.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitYieldStar(expression, location) {
+            emitWorker(7 /* YieldStar */, [expression], location);
+        }
+        /**
+         * Emits a Yield operation for the provided expression.
+         *
+         * @param expression An optional value for the yield operation.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitYield(expression, location) {
+            emitWorker(6 /* Yield */, [expression], location);
+        }
+        /**
+         * Emits a Return operation for the provided expression.
+         *
+         * @param expression An optional value for the operation.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitReturn(expression, location) {
+            emitWorker(8 /* Return */, [expression], location);
+        }
+        /**
+         * Emits a Throw operation for the provided expression.
+         *
+         * @param expression A value for the operation.
+         * @param location An optional source map location for the assignment.
+         */
+        function emitThrow(expression, location) {
+            emitWorker(9 /* Throw */, [expression], location);
+        }
+        /**
+         * Emits an Endfinally operation. This is used to handle `finally` block semantics.
+         */
+        function emitEndfinally() {
+            emitWorker(10 /* Endfinally */);
+        }
+        /**
+         * Emits an operation.
+         *
+         * @param code The OpCode for the operation.
+         * @param args The optional arguments for the operation.
+         */
+        function emitWorker(code, args, location) {
+            if (operations === undefined) {
+                operations = [];
+                operationArguments = [];
+                operationLocations = [];
+            }
+            if (labelOffsets === undefined) {
+                // mark entry point
+                markLabel(defineLabel());
+            }
+            var operationIndex = operations.length;
+            operations[operationIndex] = code;
+            operationArguments[operationIndex] = args;
+            operationLocations[operationIndex] = location;
+        }
+        /**
+         * Builds the generator function body.
+         */
+        function build() {
+            blockIndex = 0;
+            labelNumber = 0;
+            labelNumbers = undefined;
+            lastOperationWasAbrupt = false;
+            lastOperationWasCompletion = false;
+            clauses = undefined;
+            statements = undefined;
+            exceptionBlockStack = undefined;
+            currentExceptionBlock = undefined;
+            withBlockStack = undefined;
+            var buildResult = buildStatements();
+            return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], 
+            /*type*/ undefined, ts.createBlock(buildResult, 
+            /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */));
+        }
+        /**
+         * Builds the statements for the generator function body.
+         */
+        function buildStatements() {
+            if (operations) {
+                for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) {
+                    writeOperation(operationIndex);
+                }
+                flushFinalLabel(operations.length);
+            }
+            else {
+                flushFinalLabel(0);
+            }
+            if (clauses) {
+                var labelExpression = ts.createPropertyAccess(state, "label");
+                var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses));
+                switchStatement.startsOnNewLine = true;
+                return [switchStatement];
+            }
+            if (statements) {
+                return statements;
+            }
+            return [];
+        }
+        /**
+         * Flush the current label and advance to a new label.
+         */
+        function flushLabel() {
+            if (!statements) {
+                return;
+            }
+            appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt);
+            lastOperationWasAbrupt = false;
+            lastOperationWasCompletion = false;
+            labelNumber++;
+        }
+        /**
+         * Flush the final label of the generator function body.
+         */
+        function flushFinalLabel(operationIndex) {
+            if (isFinalLabelReachable(operationIndex)) {
+                tryEnterLabel(operationIndex);
+                withBlockStack = undefined;
+                writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
+            }
+            if (statements && clauses) {
+                appendLabel(/*markLabelEnd*/ false);
+            }
+            updateLabelExpressions();
+        }
+        /**
+         * Tests whether the final label of the generator function body
+         * is reachable by user code.
+         */
+        function isFinalLabelReachable(operationIndex) {
+            // if the last operation was *not* a completion (return/throw) then
+            // the final label is reachable.
+            if (!lastOperationWasCompletion) {
+                return true;
+            }
+            // if there are no labels defined or referenced, then the final label is
+            // not reachable.
+            if (!labelOffsets || !labelExpressions) {
+                return false;
+            }
+            // if the label for this offset is referenced, then the final label
+            // is reachable.
+            for (var label = 0; label < labelOffsets.length; label++) {
+                if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        /**
+         * Appends a case clause for the last label and sets the new label.
+         *
+         * @param markLabelEnd Indicates that the transition between labels was a fall-through
+         *                     from a previous case clause and the change in labels should be
+         *                     reflected on the `state` object.
+         */
+        function appendLabel(markLabelEnd) {
+            if (!clauses) {
+                clauses = [];
+            }
+            if (statements) {
+                if (withBlockStack) {
+                    // The previous label was nested inside one or more `with` blocks, so we
+                    // surround the statements in generated `with` blocks to create the same environment.
+                    for (var i = withBlockStack.length - 1; i >= 0; i--) {
+                        var withBlock = withBlockStack[i];
+                        statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))];
+                    }
+                }
+                if (currentExceptionBlock) {
+                    // The previous label was nested inside of an exception block, so we must
+                    // indicate entry into a protected region by pushing the label numbers
+                    // for each block in the protected region.
+                    var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel;
+                    statements.unshift(ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), 
+                    /*typeArguments*/ undefined, [
+                        ts.createArrayLiteral([
+                            createLabel(startLabel),
+                            createLabel(catchLabel),
+                            createLabel(finallyLabel),
+                            createLabel(endLabel)
+                        ])
+                    ])));
+                    currentExceptionBlock = undefined;
+                }
+                if (markLabelEnd) {
+                    // The case clause for the last label falls through to this label, so we
+                    // add an assignment statement to reflect the change in labels.
+                    statements.push(ts.createStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1))));
+                }
+            }
+            clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || []));
+            statements = undefined;
+        }
+        /**
+         * Tries to enter into a new label at the current operation index.
+         */
+        function tryEnterLabel(operationIndex) {
+            if (!labelOffsets) {
+                return;
+            }
+            for (var label = 0; label < labelOffsets.length; label++) {
+                if (labelOffsets[label] === operationIndex) {
+                    flushLabel();
+                    if (labelNumbers === undefined) {
+                        labelNumbers = [];
+                    }
+                    if (labelNumbers[labelNumber] === undefined) {
+                        labelNumbers[labelNumber] = [label];
+                    }
+                    else {
+                        labelNumbers[labelNumber].push(label);
+                    }
+                }
+            }
+        }
+        /**
+         * Updates literal expressions for labels with actual label numbers.
+         */
+        function updateLabelExpressions() {
+            if (labelExpressions !== undefined && labelNumbers !== undefined) {
+                for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) {
+                    var labels = labelNumbers[labelNumber_1];
+                    if (labels !== undefined) {
+                        for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) {
+                            var label = labels_1[_i];
+                            var expressions = labelExpressions[label];
+                            if (expressions !== undefined) {
+                                for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) {
+                                    var expression = expressions_1[_a];
+                                    expression.text = String(labelNumber_1);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        /**
+         * Tries to enter or leave a code block.
+         */
+        function tryEnterOrLeaveBlock(operationIndex) {
+            if (blocks) {
+                for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
+                    var block = blocks[blockIndex];
+                    var blockAction = blockActions[blockIndex];
+                    switch (block.kind) {
+                        case 0 /* Exception */:
+                            if (blockAction === 0 /* Open */) {
+                                if (!exceptionBlockStack) {
+                                    exceptionBlockStack = [];
+                                }
+                                if (!statements) {
+                                    statements = [];
+                                }
+                                exceptionBlockStack.push(currentExceptionBlock);
+                                currentExceptionBlock = block;
+                            }
+                            else if (blockAction === 1 /* Close */) {
+                                currentExceptionBlock = exceptionBlockStack.pop();
+                            }
+                            break;
+                        case 1 /* With */:
+                            if (blockAction === 0 /* Open */) {
+                                if (!withBlockStack) {
+                                    withBlockStack = [];
+                                }
+                                withBlockStack.push(block);
+                            }
+                            else if (blockAction === 1 /* Close */) {
+                                withBlockStack.pop();
+                            }
+                            break;
+                    }
+                }
+            }
+        }
+        /**
+         * Writes an operation as a statement to the current label's statement list.
+         *
+         * @param operation The OpCode of the operation
+         */
+        function writeOperation(operationIndex) {
+            tryEnterLabel(operationIndex);
+            tryEnterOrLeaveBlock(operationIndex);
+            // early termination, nothing else to process in this label
+            if (lastOperationWasAbrupt) {
+                return;
+            }
+            lastOperationWasAbrupt = false;
+            lastOperationWasCompletion = false;
+            var opcode = operations[operationIndex];
+            if (opcode === 0 /* Nop */) {
+                return;
+            }
+            else if (opcode === 10 /* Endfinally */) {
+                return writeEndfinally();
+            }
+            var args = operationArguments[operationIndex];
+            if (opcode === 1 /* Statement */) {
+                return writeStatement(args[0]);
+            }
+            var location = operationLocations[operationIndex];
+            switch (opcode) {
+                case 2 /* Assign */:
+                    return writeAssign(args[0], args[1], location);
+                case 3 /* Break */:
+                    return writeBreak(args[0], location);
+                case 4 /* BreakWhenTrue */:
+                    return writeBreakWhenTrue(args[0], args[1], location);
+                case 5 /* BreakWhenFalse */:
+                    return writeBreakWhenFalse(args[0], args[1], location);
+                case 6 /* Yield */:
+                    return writeYield(args[0], location);
+                case 7 /* YieldStar */:
+                    return writeYieldStar(args[0], location);
+                case 8 /* Return */:
+                    return writeReturn(args[0], location);
+                case 9 /* Throw */:
+                    return writeThrow(args[0], location);
+            }
+        }
+        /**
+         * Writes a statement to the current label's statement list.
+         *
+         * @param statement A statement to write.
+         */
+        function writeStatement(statement) {
+            if (statement) {
+                if (!statements) {
+                    statements = [statement];
+                }
+                else {
+                    statements.push(statement);
+                }
+            }
+        }
+        /**
+         * Writes an Assign operation to the current label's statement list.
+         *
+         * @param left The left-hand side of the assignment.
+         * @param right The right-hand side of the assignment.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeAssign(left, right, operationLocation) {
+            writeStatement(ts.setTextRange(ts.createStatement(ts.createAssignment(left, right)), operationLocation));
+        }
+        /**
+         * Writes a Throw operation to the current label's statement list.
+         *
+         * @param expression The value to throw.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeThrow(expression, operationLocation) {
+            lastOperationWasAbrupt = true;
+            lastOperationWasCompletion = true;
+            writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation));
+        }
+        /**
+         * Writes a Return operation to the current label's statement list.
+         *
+         * @param expression The value to return.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeReturn(expression, operationLocation) {
+            lastOperationWasAbrupt = true;
+            lastOperationWasCompletion = true;
+            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
+                ? [createInstruction(2 /* Return */), expression]
+                : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */));
+        }
+        /**
+         * Writes a Break operation to the current label's statement list.
+         *
+         * @param label The label for the Break.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeBreak(label, operationLocation) {
+            lastOperationWasAbrupt = true;
+            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(3 /* Break */),
+                createLabel(label)
+            ])), operationLocation), 384 /* NoTokenSourceMaps */));
+        }
+        /**
+         * Writes a BreakWhenTrue operation to the current label's statement list.
+         *
+         * @param label The label for the Break.
+         * @param condition The condition for the Break.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeBreakWhenTrue(label, condition, operationLocation) {
+            writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(3 /* Break */),
+                createLabel(label)
+            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
+        }
+        /**
+         * Writes a BreakWhenFalse operation to the current label's statement list.
+         *
+         * @param label The label for the Break.
+         * @param condition The condition for the Break.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeBreakWhenFalse(label, condition, operationLocation) {
+            writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(3 /* Break */),
+                createLabel(label)
+            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
+        }
+        /**
+         * Writes a Yield operation to the current label's statement list.
+         *
+         * @param expression The expression to yield.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeYield(expression, operationLocation) {
+            lastOperationWasAbrupt = true;
+            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
+                ? [createInstruction(4 /* Yield */), expression]
+                : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */));
+        }
+        /**
+         * Writes a YieldStar instruction to the current label's statement list.
+         *
+         * @param expression The expression to yield.
+         * @param operationLocation The source map location for the operation.
+         */
+        function writeYieldStar(expression, operationLocation) {
+            lastOperationWasAbrupt = true;
+            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(5 /* YieldStar */),
+                expression
+            ])), operationLocation), 384 /* NoTokenSourceMaps */));
+        }
+        /**
+         * Writes an Endfinally instruction to the current label's statement list.
+         */
+        function writeEndfinally() {
+            lastOperationWasAbrupt = true;
+            writeStatement(ts.createReturn(ts.createArrayLiteral([
+                createInstruction(7 /* Endfinally */)
+            ])));
+        }
+    }
+    ts.transformGenerators = transformGenerators;
+    function createGeneratorHelper(context, body) {
+        context.requestEmitHelper(generatorHelper);
+        return ts.createCall(ts.getHelperName("__generator"), 
+        /*typeArguments*/ undefined, [ts.createThis(), body]);
+    }
+    // The __generator helper is used by down-level transformations to emulate the runtime
+    // semantics of an ES2015 generator function. When called, this helper returns an
+    // object that implements the Iterator protocol, in that it has `next`, `return`, and
+    // `throw` methods that step through the generator when invoked.
+    //
+    // parameters:
+    //  thisArg  The value to use as the `this` binding for the transformed generator body.
+    //  body     A function that acts as the transformed generator body.
+    //
+    // variables:
+    //  _       Persistent state for the generator that is shared between the helper and the
+    //          generator body. The state object has the following members:
+    //            sent() - A method that returns or throws the current completion value.
+    //            label  - The next point at which to resume evaluation of the generator body.
+    //            trys   - A stack of protected regions (try/catch/finally blocks).
+    //            ops    - A stack of pending instructions when inside of a finally block.
+    //  f       A value indicating whether the generator is executing.
+    //  y       An iterator to delegate for a yield*.
+    //  t       A temporary variable that holds one of the following values (note that these
+    //          cases do not overlap):
+    //          - The completion value when resuming from a `yield` or `yield*`.
+    //          - The error value for a catch block.
+    //          - The current protected region (array of try/catch/finally/end labels).
+    //          - The verb (`next`, `throw`, or `return` method) to delegate to the expression
+    //            of a `yield*`.
+    //          - The result of evaluating the verb delegated to the expression of a `yield*`.
+    //
+    // functions:
+    //  verb(n)     Creates a bound callback to the `step` function for opcode `n`.
+    //  step(op)    Evaluates opcodes in a generator body until execution is suspended or
+    //              completed.
+    //
+    // The __generator helper understands a limited set of instructions:
+    //  0: next(value?)     - Start or resume the generator with the specified value.
+    //  1: throw(error)     - Resume the generator with an exception. If the generator is
+    //                        suspended inside of one or more protected regions, evaluates
+    //                        any intervening finally blocks between the current label and
+    //                        the nearest catch block or function boundary. If uncaught, the
+    //                        exception is thrown to the caller.
+    //  2: return(value?)   - Resume the generator as if with a return. If the generator is
+    //                        suspended inside of one or more protected regions, evaluates any
+    //                        intervening finally blocks.
+    //  3: break(label)     - Jump to the specified label. If the label is outside of the
+    //                        current protected region, evaluates any intervening finally
+    //                        blocks.
+    //  4: yield(value?)    - Yield execution to the caller with an optional value. When
+    //                        resumed, the generator will continue at the next label.
+    //  5: yield*(value)    - Delegates evaluation to the supplied iterator. When
+    //                        delegation completes, the generator will continue at the next
+    //                        label.
+    //  6: catch(error)     - Handles an exception thrown from within the generator body. If
+    //                        the current label is inside of one or more protected regions,
+    //                        evaluates any intervening finally blocks between the current
+    //                        label and the nearest catch block or function boundary. If
+    //                        uncaught, the exception is thrown to the caller.
+    //  7: endfinally       - Ends a finally block, resuming the last instruction prior to
+    //                        entering a finally block.
+    //
+    // For examples of how these are used, see the comments in ./transformers/generators.ts
+    var generatorHelper = {
+        name: "typescript:generator",
+        scoped: false,
+        priority: 6,
+        text: "\n            var __generator = (this && this.__generator) || function (thisArg, body) {\n                var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n                return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n                function verb(n) { return function (v) { return step([n, v]); }; }\n                function step(op) {\n                    if (f) throw new TypeError(\"Generator is already executing.\");\n                    while (_) try {\n                        if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n                        if (y = 0, t) op = [0, t.value];\n                        switch (op[0]) {\n                            case 0: case 1: t = op; break;\n                            case 4: _.label++; return { value: op[1], done: false };\n                            case 5: _.label++; y = op[1]; op = [0]; continue;\n                            case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                            default:\n                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                                if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                                if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                                if (t[2]) _.ops.pop();\n                                _.trys.pop(); continue;\n                        }\n                        op = body.call(thisArg, _);\n                    } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n                    if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n                }\n            };"
+    };
+})(ts || (ts = {}));
+/// <reference path="../../factory.ts" />
+/// <reference path="../../visitor.ts" />
+/// <reference path="../destructuring.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    function transformModule(context) {
+        function getTransformModuleDelegate(moduleKind) {
+            switch (moduleKind) {
+                case ts.ModuleKind.AMD: return transformAMDModule;
+                case ts.ModuleKind.UMD: return transformUMDModule;
+                default: return transformCommonJSModule;
+            }
+        }
+        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var compilerOptions = context.getCompilerOptions();
+        var resolver = context.getEmitResolver();
+        var host = context.getEmitHost();
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var moduleKind = ts.getEmitModuleKind(compilerOptions);
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        var previousOnEmitNode = context.onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        context.onEmitNode = onEmitNode;
+        context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols.
+        context.enableSubstitution(194 /* BinaryExpression */); // Substitutes assignments to exported symbols.
+        context.enableSubstitution(192 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
+        context.enableSubstitution(193 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
+        context.enableSubstitution(262 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols.
+        context.enableEmitNotification(265 /* SourceFile */); // Restore state when substituting nodes in a file.
+        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
+        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
+        var currentSourceFile; // The current file.
+        var currentModuleInfo; // The ExternalModuleInfo for the current file.
+        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
+        var needUMDDynamicImportHelper;
+        return transformSourceFile;
+        /**
+         * Transforms the module aspects of a SourceFile.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile || !(ts.isExternalModule(node) || compilerOptions.isolatedModules || node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
+                return node;
+            }
+            currentSourceFile = node;
+            currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
+            moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo;
+            // Perform the transformation.
+            var transformModule = getTransformModuleDelegate(moduleKind);
+            var updated = transformModule(node);
+            currentSourceFile = undefined;
+            currentModuleInfo = undefined;
+            needUMDDynamicImportHelper = false;
+            return ts.aggregateTransformFlags(updated);
+        }
+        function shouldEmitUnderscoreUnderscoreESModule() {
+            if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) {
+                return true;
+            }
+            return false;
+        }
+        /**
+         * Transforms a SourceFile into a CommonJS module.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformCommonJSModule(node) {
+            startLexicalEnvironment();
+            var statements = [];
+            var ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
+            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
+            if (shouldEmitUnderscoreUnderscoreESModule()) {
+                ts.append(statements, createUnderscoreUnderscoreESModule());
+            }
+            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
+            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
+            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
+            ts.addRange(statements, endLexicalEnvironment());
+            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
+            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
+                // If we have any `export * from ...` declarations
+                // we need to inform the emitter to add the __export helper.
+                ts.addEmitHelper(updated, exportStarHelper);
+            }
+            ts.addEmitHelpers(updated, context.readEmitHelpers());
+            return updated;
+        }
+        /**
+         * Transforms a SourceFile into an AMD module.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformAMDModule(node) {
+            var define = ts.createIdentifier("define");
+            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
+            // An AMD define function has the following shape:
+            //
+            //     define(id?, dependencies?, factory);
+            //
+            // This has the shape of the following:
+            //
+            //     define(name, ["module1", "module2"], function (module1Alias) { ... }
+            //
+            // The location of the alias in the parameter list in the factory function needs to
+            // match the position of the module name in the dependency list.
+            //
+            // To ensure this is true in cases of modules with no aliases, e.g.:
+            //
+            //     import "module"
+            //
+            // or
+            //
+            //     /// <amd-dependency path= "a.css" />
+            //
+            // we need to add modules without alias names to the end of the dependencies list
+            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
+            // Create an updated SourceFile:
+            //
+            //     define(moduleName?, ["module1", "module2"], function ...
+            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
+                ts.createStatement(ts.createCall(define, 
+                /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
+                    // Add the dependency array argument:
+                    //
+                    //     ["require", "exports", module1", "module2", ...]
+                    ts.createArrayLiteral([
+                        ts.createLiteral("require"),
+                        ts.createLiteral("exports")
+                    ].concat(aliasedModuleNames, unaliasedModuleNames)),
+                    // Add the module body function argument:
+                    //
+                    //     function (require, exports, module1, module2) ...
+                    ts.createFunctionExpression(
+                    /*modifiers*/ undefined, 
+                    /*asteriskToken*/ undefined, 
+                    /*name*/ undefined, 
+                    /*typeParameters*/ undefined, [
+                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
+                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
+                    ].concat(importAliasNames), 
+                    /*type*/ undefined, transformAsynchronousModuleBody(node))
+                ])))
+            ]), 
+            /*location*/ node.statements));
+        }
+        /**
+         * Transforms a SourceFile into a UMD module.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformUMDModule(node) {
+            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
+            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
+            var umdHeader = ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], 
+            /*type*/ undefined, ts.setTextRange(ts.createBlock([
+                ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([
+                    ts.createVariableStatement(
+                    /*modifiers*/ undefined, [
+                        ts.createVariableDeclaration("v", 
+                        /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), 
+                        /*typeArguments*/ undefined, [
+                            ts.createIdentifier("require"),
+                            ts.createIdentifier("exports")
+                        ]))
+                    ]),
+                    ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */)
+                ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([
+                    ts.createStatement(ts.createCall(ts.createIdentifier("define"), 
+                    /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
+                        ts.createArrayLiteral([
+                            ts.createLiteral("require"),
+                            ts.createLiteral("exports")
+                        ].concat(aliasedModuleNames, unaliasedModuleNames)),
+                        ts.createIdentifier("factory")
+                    ])))
+                ])))
+            ], 
+            /*multiLine*/ true), 
+            /*location*/ undefined));
+            // Create an updated SourceFile:
+            //
+            //  (function (factory) {
+            //      if (typeof module === "object" && typeof module.exports === "object") {
+            //          var v = factory(require, exports);
+            //          if (v !== undefined) module.exports = v;
+            //      }
+            //      else if (typeof define === 'function' && define.amd) {
+            //          define(["require", "exports"], factory);
+            //      }
+            //  })(function ...)
+            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
+                ts.createStatement(ts.createCall(umdHeader, 
+                /*typeArguments*/ undefined, [
+                    // Add the module body function argument:
+                    //
+                    //     function (require, exports) ...
+                    ts.createFunctionExpression(
+                    /*modifiers*/ undefined, 
+                    /*asteriskToken*/ undefined, 
+                    /*name*/ undefined, 
+                    /*typeParameters*/ undefined, [
+                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
+                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
+                    ].concat(importAliasNames), 
+                    /*type*/ undefined, transformAsynchronousModuleBody(node))
+                ]))
+            ]), 
+            /*location*/ node.statements));
+        }
+        /**
+         * Collect the additional asynchronous dependencies for the module.
+         *
+         * @param node The source file.
+         * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies.
+         */
+        function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
+            // names of modules with corresponding parameter in the factory function
+            var aliasedModuleNames = [];
+            // names of modules with no corresponding parameters in factory function
+            var unaliasedModuleNames = [];
+            // names of the parameters in the factory function; these
+            // parameters need to match the indexes of the corresponding
+            // module names in aliasedModuleNames.
+            var importAliasNames = [];
+            // Fill in amd-dependency tags
+            for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) {
+                var amdDependency = _a[_i];
+                if (amdDependency.name) {
+                    aliasedModuleNames.push(ts.createLiteral(amdDependency.path));
+                    importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name));
+                }
+                else {
+                    unaliasedModuleNames.push(ts.createLiteral(amdDependency.path));
+                }
+            }
+            for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) {
+                var importNode = _c[_b];
+                // Find the name of the external module
+                var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
+                // Find the name of the module alias, if there is one
+                var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile);
+                // It is possible that externalModuleName is undefined if it is not string literal.
+                // This can happen in the invalid import syntax.
+                // E.g : "import * from alias from 'someLib';"
+                if (externalModuleName) {
+                    if (includeNonAmdDependencies && importAliasName) {
+                        // Set emitFlags on the name of the classDeclaration
+                        // This is so that when printer will not substitute the identifier
+                        ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */);
+                        aliasedModuleNames.push(externalModuleName);
+                        importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
+                    }
+                    else {
+                        unaliasedModuleNames.push(externalModuleName);
+                    }
+                }
+            }
+            return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
+        }
+        /**
+         * Transforms a SourceFile into an AMD or UMD module body.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformAsynchronousModuleBody(node) {
+            startLexicalEnvironment();
+            var statements = [];
+            var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
+            if (shouldEmitUnderscoreUnderscoreESModule()) {
+                ts.append(statements, createUnderscoreUnderscoreESModule());
+            }
+            // Visit each statement of the module body.
+            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
+            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
+            // Append the 'export =' statement if provided.
+            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
+            // End the lexical environment for the module body
+            // and merge any new lexical declarations.
+            ts.addRange(statements, endLexicalEnvironment());
+            var body = ts.createBlock(statements, /*multiLine*/ true);
+            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
+                // If we have any `export * from ...` declarations
+                // we need to inform the emitter to add the __export helper.
+                ts.addEmitHelper(body, exportStarHelper);
+            }
+            if (needUMDDynamicImportHelper) {
+                ts.addEmitHelper(body, dynamicImportUMDHelper);
+            }
+            return body;
+        }
+        /**
+         * Adds the down-level representation of `export=` to the statement list if one exists
+         * in the source file.
+         *
+         * @param statements The Statement list to modify.
+         * @param emitAsReturn A value indicating whether to emit the `export=` statement as a
+         * return statement.
+         */
+        function addExportEqualsIfNeeded(statements, emitAsReturn) {
+            if (currentModuleInfo.exportEquals) {
+                var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, importCallExpressionVisitor);
+                if (expressionResult) {
+                    if (emitAsReturn) {
+                        var statement = ts.createReturn(expressionResult);
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
+                        statements.push(statement);
+                    }
+                    else {
+                        var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536 /* NoComments */);
+                        statements.push(statement);
+                    }
+                }
+            }
+        }
+        //
+        // Top-Level Source Element Visitors
+        //
+        /**
+         * Visits a node at the top level of the source file.
+         *
+         * @param node The node to visit.
+         */
+        function sourceElementVisitor(node) {
+            switch (node.kind) {
+                case 238 /* ImportDeclaration */:
+                    return visitImportDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return visitImportEqualsDeclaration(node);
+                case 244 /* ExportDeclaration */:
+                    return visitExportDeclaration(node);
+                case 243 /* ExportAssignment */:
+                    return visitExportAssignment(node);
+                case 208 /* VariableStatement */:
+                    return visitVariableStatement(node);
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 229 /* ClassDeclaration */:
+                    return visitClassDeclaration(node);
+                case 290 /* MergeDeclarationMarker */:
+                    return visitMergeDeclarationMarker(node);
+                case 291 /* EndOfDeclarationMarker */:
+                    return visitEndOfDeclarationMarker(node);
+                default:
+                    return ts.visitEachChild(node, importCallExpressionVisitor, context);
+            }
+        }
+        function importCallExpressionVisitor(node) {
+            // This visitor does not need to descend into the tree if there is no dynamic import,
+            // as export/import statements are only transformed at the top level of a file.
+            if (!(node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
+                return node;
+            }
+            if (ts.isImportCall(node)) {
+                return visitImportCallExpression(node);
+            }
+            else {
+                return ts.visitEachChild(node, importCallExpressionVisitor, context);
+            }
+        }
+        function visitImportCallExpression(node) {
+            var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), importCallExpressionVisitor);
+            var containsLexicalThis = !!(node.transformFlags & 16384 /* ContainsLexicalThis */);
+            switch (compilerOptions.module) {
+                case ts.ModuleKind.AMD:
+                    return createImportCallExpressionAMD(argument, containsLexicalThis);
+                case ts.ModuleKind.UMD:
+                    return createImportCallExpressionUMD(argument, containsLexicalThis);
+                case ts.ModuleKind.CommonJS:
+                default:
+                    return createImportCallExpressionCommonJS(argument, containsLexicalThis);
+            }
+        }
+        function createImportCallExpressionUMD(arg, containsLexicalThis) {
+            // (function (factory) {
+            //      ... (regular UMD)
+            // }
+            // })(function (require, exports, useSyncRequire) {
+            //      "use strict";
+            //      Object.defineProperty(exports, "__esModule", { value: true });
+            //      var __syncRequire = typeof module === "object" && typeof module.exports === "object";
+            //      var __resolved = new Promise(function (resolve) { resolve(); });
+            //      .....
+            //      __syncRequire
+            //          ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/
+            //          : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
+            // });
+            needUMDDynamicImportHelper = true;
+            if (ts.isSimpleCopiableExpression(arg)) {
+                var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */);
+                return ts.createConditional(
+                /*condition*/ ts.createIdentifier("__syncRequire"), 
+                /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), 
+                /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis));
+            }
+            else {
+                var temp = ts.createTempVariable(hoistVariableDeclaration);
+                return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional(
+                /*condition*/ ts.createIdentifier("__syncRequire"), 
+                /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), 
+                /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis)));
+            }
+        }
+        function createImportCallExpressionAMD(arg, containsLexicalThis) {
+            // improt("./blah")
+            // emit as
+            // define(["require", "exports", "blah"], function (require, exports) {
+            //     ...
+            //     new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
+            // });
+            var resolve = ts.createUniqueName("resolve");
+            var reject = ts.createUniqueName("reject");
+            var parameters = [
+                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
+                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
+            ];
+            var body = ts.createBlock([
+                ts.createStatement(ts.createCall(ts.createIdentifier("require"), 
+                /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject]))
+            ]);
+            var func;
+            if (languageVersion >= 2 /* ES2015 */) {
+                func = ts.createArrowFunction(
+                /*modifiers*/ undefined, 
+                /*typeParameters*/ undefined, parameters, 
+                /*type*/ undefined, 
+                /*equalsGreaterThanToken*/ undefined, body);
+            }
+            else {
+                func = ts.createFunctionExpression(
+                /*modifiers*/ undefined, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, parameters, 
+                /*type*/ undefined, body);
+                // if there is a lexical 'this' in the import call arguments, ensure we indicate
+                // that this new function expression indicates it captures 'this' so that the
+                // es2015 transformer will properly substitute 'this' with '_this'.
+                if (containsLexicalThis) {
+                    ts.setEmitFlags(func, 8 /* CapturesThis */);
+                }
+            }
+            return ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
+        }
+        function createImportCallExpressionCommonJS(arg, containsLexicalThis) {
+            // import("./blah")
+            // emit as
+            // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
+            // We have to wrap require in then callback so that require is done in asynchronously
+            // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
+            var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
+            var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
+            var func;
+            if (languageVersion >= 2 /* ES2015 */) {
+                func = ts.createArrowFunction(
+                /*modifiers*/ undefined, 
+                /*typeParameters*/ undefined, 
+                /*parameters*/ [], 
+                /*type*/ undefined, 
+                /*equalsGreaterThanToken*/ undefined, requireCall);
+            }
+            else {
+                func = ts.createFunctionExpression(
+                /*modifiers*/ undefined, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, 
+                /*parameters*/ [], 
+                /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)]));
+                // if there is a lexical 'this' in the import call arguments, ensure we indicate
+                // that this new function expression indicates it captures 'this' so that the
+                // es2015 transformer will properly substitute 'this' with '_this'.
+                if (containsLexicalThis) {
+                    ts.setEmitFlags(func, 8 /* CapturesThis */);
+                }
+            }
+            return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
+        }
+        /**
+         * Visits an ImportDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitImportDeclaration(node) {
+            var statements;
+            var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
+            if (moduleKind !== ts.ModuleKind.AMD) {
+                if (!node.importClause) {
+                    // import "mod";
+                    return ts.setTextRange(ts.createStatement(createRequireCall(node)), node);
+                }
+                else {
+                    var variables = [];
+                    if (namespaceDeclaration && !ts.isDefaultImport(node)) {
+                        // import * as n from "mod";
+                        variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
+                        /*type*/ undefined, createRequireCall(node)));
+                    }
+                    else {
+                        // import d from "mod";
+                        // import { x, y } from "mod";
+                        // import d, { x, y } from "mod";
+                        // import d, * as n from "mod";
+                        variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), 
+                        /*type*/ undefined, createRequireCall(node)));
+                        if (namespaceDeclaration && ts.isDefaultImport(node)) {
+                            variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
+                            /*type*/ undefined, ts.getGeneratedNameForNode(node)));
+                        }
+                    }
+                    statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement(
+                    /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), 
+                    /*location*/ node));
+                }
+            }
+            else if (namespaceDeclaration && ts.isDefaultImport(node)) {
+                // import d, * as n from "mod";
+                statements = ts.append(statements, ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                    ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
+                    /*type*/ undefined, ts.getGeneratedNameForNode(node)), 
+                    /*location*/ node)
+                ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfImportDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Creates a `require()` call to import an external module.
+         *
+         * @param importNode The declararation to import.
+         */
+        function createRequireCall(importNode) {
+            var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
+            var args = [];
+            if (moduleName) {
+                args.push(moduleName);
+            }
+            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args);
+        }
+        /**
+         * Visits an ImportEqualsDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitImportEqualsDeclaration(node) {
+            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
+            var statements;
+            if (moduleKind !== ts.ModuleKind.AMD) {
+                if (ts.hasModifier(node, 1 /* Export */)) {
+                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(node.name, createRequireCall(node))), node));
+                }
+                else {
+                    statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement(
+                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                        ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), 
+                        /*type*/ undefined, createRequireCall(node))
+                    ], 
+                    /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node));
+                }
+            }
+            else {
+                if (ts.hasModifier(node, 1 /* Export */)) {
+                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node));
+                }
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfImportEqualsDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits an ExportDeclaration node.
+         *
+         * @param The node to visit.
+         */
+        function visitExportDeclaration(node) {
+            if (!node.moduleSpecifier) {
+                // Elide export declarations with no module specifier as they are handled
+                // elsewhere.
+                return undefined;
+            }
+            var generatedName = ts.getGeneratedNameForNode(node);
+            if (node.exportClause) {
+                var statements = [];
+                // export { x, y } from "mod";
+                if (moduleKind !== ts.ModuleKind.AMD) {
+                    statements.push(ts.setTextRange(ts.createVariableStatement(
+                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                        ts.createVariableDeclaration(generatedName, 
+                        /*type*/ undefined, createRequireCall(node))
+                    ])), 
+                    /*location*/ node));
+                }
+                for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
+                    var specifier = _a[_i];
+                    var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name);
+                    statements.push(ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(specifier), exportedValue)), specifier));
+                }
+                return ts.singleOrMany(statements);
+            }
+            else {
+                // export * from "mod";
+                return ts.setTextRange(ts.createStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node);
+            }
+        }
+        /**
+         * Visits an ExportAssignment node.
+         *
+         * @param node The node to visit.
+         */
+        function visitExportAssignment(node) {
+            if (node.isExportEquals) {
+                return undefined;
+            }
+            var statements;
+            var original = node.original;
+            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
+            }
+            else {
+                statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits a FunctionDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionDeclaration(node) {
+            var statements;
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
+                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
+                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, importCallExpressionVisitor), 
+                /*type*/ undefined, ts.visitEachChild(node.body, importCallExpressionVisitor, context)), 
+                /*location*/ node), 
+                /*original*/ node));
+            }
+            else {
+                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfHoistedDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits a ClassDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitClassDeclaration(node) {
+            var statements;
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration(
+                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
+                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, importCallExpressionVisitor), ts.visitNodes(node.members, importCallExpressionVisitor)), node), node));
+            }
+            else {
+                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfHoistedDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits a VariableStatement node.
+         *
+         * @param node The node to visit.
+         */
+        function visitVariableStatement(node) {
+            var statements;
+            var variables;
+            var expressions;
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                var modifiers = void 0;
+                // If we're exporting these variables, then these just become assignments to 'exports.x'.
+                // We only want to emit assignments for variables with initializers.
+                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                    var variable = _a[_i];
+                    if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) {
+                        if (!modifiers) {
+                            modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier);
+                        }
+                        variables = ts.append(variables, variable);
+                    }
+                    else if (variable.initializer) {
+                        expressions = ts.append(expressions, transformInitializedVariable(variable));
+                    }
+                }
+                if (variables) {
+                    statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables)));
+                }
+                if (expressions) {
+                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node));
+                }
+            }
+            else {
+                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfVariableStatement(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Transforms an exported variable with an initializer into an expression.
+         *
+         * @param node The node to transform.
+         */
+        function transformInitializedVariable(node) {
+            if (ts.isBindingPattern(node.name)) {
+                return ts.flattenDestructuringAssignment(ts.visitNode(node, importCallExpressionVisitor), 
+                /*visitor*/ undefined, context, 0 /* All */, 
+                /*needsValue*/ false, createExportExpression);
+            }
+            else {
+                return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), 
+                /*location*/ node.name), ts.visitNode(node.initializer, importCallExpressionVisitor));
+            }
+        }
+        /**
+         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
+         * and transformed declaration.
+         *
+         * @param node The node to visit.
+         */
+        function visitMergeDeclarationMarker(node) {
+            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
+            // declaration we do not emit a leading variable declaration. To preserve the
+            // begin/end semantics of the declararation and to properly handle exports
+            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
+            //
+            // To balance the declaration, add the exports of the elided variable
+            // statement.
+            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 208 /* VariableStatement */) {
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original);
+            }
+            return node;
+        }
+        /**
+         * Determines whether a node has an associated EndOfDeclarationMarker.
+         *
+         * @param node The node to test.
+         */
+        function hasAssociatedEndOfDeclarationMarker(node) {
+            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
+        }
+        /**
+         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
+         * declaration.
+         *
+         * @param node The node to visit.
+         */
+        function visitEndOfDeclarationMarker(node) {
+            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
+            // end of the transformed declaration. We use this marker to emit any deferred exports
+            // of the declaration.
+            var id = ts.getOriginalNodeId(node);
+            var statements = deferredExports[id];
+            if (statements) {
+                delete deferredExports[id];
+                return ts.append(statements, node);
+            }
+            return node;
+        }
+        /**
+         * Appends the exports of an ImportDeclaration to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfImportDeclaration(statements, decl) {
+            if (currentModuleInfo.exportEquals) {
+                return statements;
+            }
+            var importClause = decl.importClause;
+            if (!importClause) {
+                return statements;
+            }
+            if (importClause.name) {
+                statements = appendExportsOfDeclaration(statements, importClause);
+            }
+            var namedBindings = importClause.namedBindings;
+            if (namedBindings) {
+                switch (namedBindings.kind) {
+                    case 240 /* NamespaceImport */:
+                        statements = appendExportsOfDeclaration(statements, namedBindings);
+                        break;
+                    case 241 /* NamedImports */:
+                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
+                            var importBinding = _a[_i];
+                            statements = appendExportsOfDeclaration(statements, importBinding);
+                        }
+                        break;
+                }
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfImportEqualsDeclaration(statements, decl) {
+            if (currentModuleInfo.exportEquals) {
+                return statements;
+            }
+            return appendExportsOfDeclaration(statements, decl);
+        }
+        /**
+         * Appends the exports of a VariableStatement to a statement list, returning the statement
+         * list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param node The VariableStatement whose exports are to be recorded.
+         */
+        function appendExportsOfVariableStatement(statements, node) {
+            if (currentModuleInfo.exportEquals) {
+                return statements;
+            }
+            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                var decl = _a[_i];
+                statements = appendExportsOfBindingElement(statements, decl);
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
+         * returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfBindingElement(statements, decl) {
+            if (currentModuleInfo.exportEquals) {
+                return statements;
+            }
+            if (ts.isBindingPattern(decl.name)) {
+                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        statements = appendExportsOfBindingElement(statements, element);
+                    }
+                }
+            }
+            else if (!ts.isGeneratedIdentifier(decl.name)) {
+                statements = appendExportsOfDeclaration(statements, decl);
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
+         * returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfHoistedDeclaration(statements, decl) {
+            if (currentModuleInfo.exportEquals) {
+                return statements;
+            }
+            if (ts.hasModifier(decl, 1 /* Export */)) {
+                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
+                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl);
+            }
+            if (decl.name) {
+                statements = appendExportsOfDeclaration(statements, decl);
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a declaration to a statement list, returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration to export.
+         */
+        function appendExportsOfDeclaration(statements, decl) {
+            var name = ts.getDeclarationName(decl);
+            var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name));
+            if (exportSpecifiers) {
+                for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) {
+                    var exportSpecifier = exportSpecifiers_1[_i];
+                    statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
+                }
+            }
+            return statements;
+        }
+        /**
+         * Appends the down-level representation of an export to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param exportName The name of the export.
+         * @param expression The expression to export.
+         * @param location The location to use for source maps and comments for the export.
+         * @param allowComments Whether to allow comments on the export.
+         */
+        function appendExportStatement(statements, exportName, expression, location, allowComments) {
+            statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments));
+            return statements;
+        }
+        function createUnderscoreUnderscoreESModule() {
+            var statement;
+            if (languageVersion === 0 /* ES3 */) {
+                statement = ts.createStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true)));
+            }
+            else {
+                statement = ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
+                /*typeArguments*/ undefined, [
+                    ts.createIdentifier("exports"),
+                    ts.createLiteral("__esModule"),
+                    ts.createObjectLiteral([
+                        ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true))
+                    ])
+                ]));
+            }
+            ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
+            return statement;
+        }
+        /**
+         * Creates a call to the current file's export function to export a value.
+         *
+         * @param name The bound name of the export.
+         * @param value The exported value.
+         * @param location The location to use for source maps and comments for the export.
+         * @param allowComments An optional value indicating whether to emit comments for the statement.
+         */
+        function createExportStatement(name, value, location, allowComments) {
+            var statement = ts.setTextRange(ts.createStatement(createExportExpression(name, value)), location);
+            ts.startOnNewLine(statement);
+            if (!allowComments) {
+                ts.setEmitFlags(statement, 1536 /* NoComments */);
+            }
+            return statement;
+        }
+        /**
+         * Creates a call to the current file's export function to export a value.
+         *
+         * @param name The bound name of the export.
+         * @param value The exported value.
+         * @param location The location to use for source maps and comments for the export.
+         */
+        function createExportExpression(name, value, location) {
+            return ts.setTextRange(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location);
+        }
+        //
+        // Modifier Visitors
+        //
+        /**
+         * Visit nodes to elide module-specific modifiers.
+         *
+         * @param node The node to visit.
+         */
+        function modifierVisitor(node) {
+            // Elide module-specific modifiers.
+            switch (node.kind) {
+                case 84 /* ExportKeyword */:
+                case 79 /* DefaultKeyword */:
+                    return undefined;
+            }
+            return node;
+        }
+        //
+        // Emit Notification
+        //
+        /**
+         * Hook for node emit notifications.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emit A callback used to emit the node in the printer.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            if (node.kind === 265 /* SourceFile */) {
+                currentSourceFile = node;
+                currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)];
+                noSubstitution = [];
+                previousOnEmitNode(hint, node, emitCallback);
+                currentSourceFile = undefined;
+                currentModuleInfo = undefined;
+                noSubstitution = undefined;
+            }
+            else {
+                previousOnEmitNode(hint, node, emitCallback);
+            }
+        }
+        //
+        // Substitutions
+        //
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (node.id && noSubstitution[node.id]) {
+                return node;
+            }
+            if (hint === 1 /* Expression */) {
+                return substituteExpression(node);
+            }
+            else if (ts.isShorthandPropertyAssignment(node)) {
+                return substituteShorthandPropertyAssignment(node);
+            }
+            return node;
+        }
+        /**
+         * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported
+         * or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteShorthandPropertyAssignment(node) {
+            var name = node.name;
+            var exportedOrImportedName = substituteExpressionIdentifier(name);
+            if (exportedOrImportedName !== name) {
+                // A shorthand property with an assignment initializer is probably part of a
+                // destructuring assignment
+                if (node.objectAssignmentInitializer) {
+                    var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
+                    return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
+                }
+                return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node);
+            }
+            return node;
+        }
+        /**
+         * Substitution for an Expression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return substituteExpressionIdentifier(node);
+                case 194 /* BinaryExpression */:
+                    return substituteBinaryExpression(node);
+                case 193 /* PostfixUnaryExpression */:
+                case 192 /* PrefixUnaryExpression */:
+                    return substituteUnaryExpression(node);
+            }
+            return node;
+        }
+        /**
+         * Substitution for an Identifier expression that may contain an imported or exported
+         * symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteExpressionIdentifier(node) {
+            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
+                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
+                if (externalHelpersModuleName) {
+                    return ts.createPropertyAccess(externalHelpersModuleName, node);
+                }
+                return node;
+            }
+            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
+                var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node));
+                if (exportContainer && exportContainer.kind === 265 /* SourceFile */) {
+                    return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), 
+                    /*location*/ node);
+                }
+                var importDeclaration = resolver.getReferencedImportDeclaration(node);
+                if (importDeclaration) {
+                    if (ts.isImportClause(importDeclaration)) {
+                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
+                        /*location*/ node);
+                    }
+                    else if (ts.isImportSpecifier(importDeclaration)) {
+                        var name = importDeclaration.propertyName || importDeclaration.name;
+                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), 
+                        /*location*/ node);
+                    }
+                }
+            }
+            return node;
+        }
+        /**
+         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteBinaryExpression(node) {
+            // When we see an assignment expression whose left-hand side is an exported symbol,
+            // we should ensure all exports of that symbol are updated with the correct value.
+            //
+            // - We do not substitute generated identifiers for any reason.
+            // - We do not substitute identifiers tagged with the LocalName flag.
+            // - We do not substitute identifiers that were originally the name of an enum or
+            //   namespace due to how they are transformed in TypeScript.
+            // - We only substitute identifiers that are exported at the top level.
+            if (ts.isAssignmentOperator(node.operatorToken.kind)
+                && ts.isIdentifier(node.left)
+                && !ts.isGeneratedIdentifier(node.left)
+                && !ts.isLocalName(node.left)
+                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
+                var exportedNames = getExports(node.left);
+                if (exportedNames) {
+                    // For each additional export of the declaration, apply an export assignment.
+                    var expression = node;
+                    for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) {
+                        var exportName = exportedNames_1[_i];
+                        // Mark the node to prevent triggering this rule again.
+                        noSubstitution[ts.getNodeId(expression)] = true;
+                        expression = createExportExpression(exportName, expression, /*location*/ node);
+                    }
+                    return expression;
+                }
+            }
+            return node;
+        }
+        /**
+         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteUnaryExpression(node) {
+            // When we see a prefix or postfix increment expression whose operand is an exported
+            // symbol, we should ensure all exports of that symbol are updated with the correct
+            // value.
+            //
+            // - We do not substitute generated identifiers for any reason.
+            // - We do not substitute identifiers tagged with the LocalName flag.
+            // - We do not substitute identifiers that were originally the name of an enum or
+            //   namespace due to how they are transformed in TypeScript.
+            // - We only substitute identifiers that are exported at the top level.
+            if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */)
+                && ts.isIdentifier(node.operand)
+                && !ts.isGeneratedIdentifier(node.operand)
+                && !ts.isLocalName(node.operand)
+                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
+                var exportedNames = getExports(node.operand);
+                if (exportedNames) {
+                    var expression = node.kind === 193 /* PostfixUnaryExpression */
+                        ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 43 /* PlusPlusToken */ ? 59 /* PlusEqualsToken */ : 60 /* MinusEqualsToken */), ts.createLiteral(1)), 
+                        /*location*/ node)
+                        : node;
+                    for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) {
+                        var exportName = exportedNames_2[_i];
+                        // Mark the node to prevent triggering this rule again.
+                        noSubstitution[ts.getNodeId(expression)] = true;
+                        expression = createExportExpression(exportName, expression);
+                    }
+                    return expression;
+                }
+            }
+            return node;
+        }
+        /**
+         * Gets the additional exports of a name.
+         *
+         * @param name The name.
+         */
+        function getExports(name) {
+            if (!ts.isGeneratedIdentifier(name)) {
+                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
+                    || resolver.getReferencedValueDeclaration(name);
+                if (valueDeclaration) {
+                    return currentModuleInfo
+                        && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)];
+                }
+            }
+        }
+    }
+    ts.transformModule = transformModule;
+    // emit output for the __export helper function
+    var exportStarHelper = {
+        name: "typescript:export-star",
+        scoped: true,
+        text: "\n            function __export(m) {\n                for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n            }\n        "
+    };
+    function createExportStarHelper(context, module) {
+        var compilerOptions = context.getCompilerOptions();
+        return compilerOptions.importHelpers
+            ? ts.createCall(ts.getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")])
+            : ts.createCall(ts.createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
+    }
+    // emit helper for dynamic import
+    var dynamicImportUMDHelper = {
+        name: "typescript:dynamicimport-sync-require",
+        scoped: true,
+        text: "\n            var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";"
+    };
+})(ts || (ts = {}));
+/// <reference path="../../factory.ts" />
+/// <reference path="../../visitor.ts" />
+/// <reference path="../destructuring.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    function transformSystemModule(context) {
+        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
+        var compilerOptions = context.getCompilerOptions();
+        var resolver = context.getEmitResolver();
+        var host = context.getEmitHost();
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        var previousOnEmitNode = context.onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        context.onEmitNode = onEmitNode;
+        context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers for imported symbols.
+        context.enableSubstitution(194 /* BinaryExpression */); // Substitutes assignments to exported symbols.
+        context.enableSubstitution(192 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
+        context.enableSubstitution(193 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
+        context.enableEmitNotification(265 /* SourceFile */); // Restore state when substituting nodes in a file.
+        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
+        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
+        var exportFunctionsMap = []; // The export function associated with a source file.
+        var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file.
+        var currentSourceFile; // The current file.
+        var moduleInfo; // ExternalModuleInfo for the current file.
+        var exportFunction; // The export function for the current file.
+        var contextObject; // The context object for the current file.
+        var hoistedStatements;
+        var enclosingBlockScopedContainer;
+        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
+        return transformSourceFile;
+        /**
+         * Transforms the module aspects of a SourceFile.
+         *
+         * @param node The SourceFile node.
+         */
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
+                return node;
+            }
+            var id = ts.getOriginalNodeId(node);
+            currentSourceFile = node;
+            enclosingBlockScopedContainer = node;
+            // System modules have the following shape:
+            //
+            //     System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
+            //
+            // The parameter 'exports' here is a callback '<T>(name: string, value: T) => T' that
+            // is used to publish exported values. 'exports' returns its 'value' argument so in
+            // most cases expressions that mutate exported values can be rewritten as:
+            //
+            //     expr -> exports('name', expr)
+            //
+            // The only exception in this rule is postfix unary operators,
+            // see comment to 'substitutePostfixUnaryExpression' for more details
+            // Collect information about the external module and dependency groups.
+            moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
+            // Make sure that the name of the 'exports' function does not conflict with
+            // existing identifiers.
+            exportFunction = ts.createUniqueName("exports");
+            exportFunctionsMap[id] = exportFunction;
+            contextObject = ts.createUniqueName("context");
+            // Add the body of the module.
+            var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
+            var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
+            var moduleBodyFunction = ts.createFunctionExpression(
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, 
+            /*name*/ undefined, 
+            /*typeParameters*/ undefined, [
+                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction),
+                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
+            ], 
+            /*type*/ undefined, moduleBodyBlock);
+            // Write the call to `System.register`
+            // Clear the emit-helpers flag for later passes since we'll have already used it in the module body
+            // So the helper will be emit at the correct position instead of at the top of the source-file
+            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
+            var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; }));
+            var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
+                ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), 
+                /*typeArguments*/ undefined, moduleName
+                    ? [moduleName, dependencies, moduleBodyFunction]
+                    : [dependencies, moduleBodyFunction]))
+            ]), node.statements)), 1024 /* NoTrailingComments */);
+            if (!(compilerOptions.outFile || compilerOptions.out)) {
+                ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; });
+            }
+            if (noSubstitution) {
+                noSubstitutionMap[id] = noSubstitution;
+                noSubstitution = undefined;
+            }
+            currentSourceFile = undefined;
+            moduleInfo = undefined;
+            exportFunction = undefined;
+            contextObject = undefined;
+            hoistedStatements = undefined;
+            enclosingBlockScopedContainer = undefined;
+            return ts.aggregateTransformFlags(updated);
+        }
+        /**
+         * Collects the dependency groups for this files imports.
+         *
+         * @param externalImports The imports for the file.
+         */
+        function collectDependencyGroups(externalImports) {
+            var groupIndices = ts.createMap();
+            var dependencyGroups = [];
+            for (var i = 0; i < externalImports.length; i++) {
+                var externalImport = externalImports[i];
+                var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
+                if (externalModuleName) {
+                    var text = externalModuleName.text;
+                    var groupIndex = groupIndices.get(text);
+                    if (groupIndex !== undefined) {
+                        // deduplicate/group entries in dependency list by the dependency name
+                        dependencyGroups[groupIndex].externalImports.push(externalImport);
+                    }
+                    else {
+                        groupIndices.set(text, dependencyGroups.length);
+                        dependencyGroups.push({
+                            name: externalModuleName,
+                            externalImports: [externalImport]
+                        });
+                    }
+                }
+            }
+            return dependencyGroups;
+        }
+        /**
+         * Adds the statements for the module body function for the source file.
+         *
+         * @param node The source file for the module.
+         * @param dependencyGroups The grouped dependencies of the module.
+         */
+        function createSystemModuleBody(node, dependencyGroups) {
+            // Shape of the body in system modules:
+            //
+            //  function (exports) {
+            //      <list of local aliases for imports>
+            //      <hoisted variable declarations>
+            //      <hoisted function declarations>
+            //      return {
+            //          setters: [
+            //              <list of setter function for imports>
+            //          ],
+            //          execute: function() {
+            //              <module statements>
+            //          }
+            //      }
+            //      <temp declarations>
+            //  }
+            //
+            // i.e:
+            //
+            //   import {x} from 'file1'
+            //   var y = 1;
+            //   export function foo() { return y + x(); }
+            //   console.log(y);
+            //
+            // Will be transformed to:
+            //
+            //  function(exports) {
+            //      function foo() { return y + file_1.x(); }
+            //      exports("foo", foo);
+            //      var file_1, y;
+            //      return {
+            //          setters: [
+            //              function(v) { file_1 = v }
+            //          ],
+            //          execute(): function() {
+            //              y = 1;
+            //              console.log(y);
+            //          }
+            //      };
+            //  }
+            var statements = [];
+            // We start a new lexical environment in this function body, but *not* in the
+            // body of the execute function. This allows us to emit temporary declarations
+            // only in the outer module body and not in the inner one.
+            startLexicalEnvironment();
+            // Add any prologue directives.
+            var ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
+            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
+            // var __moduleName = context_1 && context_1.id;
+            statements.push(ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                ts.createVariableDeclaration("__moduleName", 
+                /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id")))
+            ])));
+            // Visit the synthetic external helpers import declaration if present
+            ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement);
+            // Visit the statements of the source file, emitting any transformations into
+            // the `executeStatements` array. We do this *before* we fill the `setters` array
+            // as we both emit transformations as well as aggregate some data used when creating
+            // setters. This allows us to reduce the number of times we need to loop through the
+            // statements of the source file.
+            var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset);
+            // Emit early exports for function declarations.
+            ts.addRange(statements, hoistedStatements);
+            // We emit hoisted variables early to align roughly with our previous emit output.
+            // Two key differences in this approach are:
+            // - Temporary variables will appear at the top rather than at the bottom of the file
+            ts.addRange(statements, endLexicalEnvironment());
+            var exportStarFunction = addExportStarIfNeeded(statements);
+            var moduleObject = ts.createObjectLiteral([
+                ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
+                ts.createPropertyAssignment("execute", ts.createFunctionExpression(
+                /*modifiers*/ undefined, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, 
+                /*parameters*/ [], 
+                /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true)))
+            ]);
+            moduleObject.multiLine = true;
+            statements.push(ts.createReturn(moduleObject));
+            return ts.createBlock(statements, /*multiLine*/ true);
+        }
+        /**
+         * Adds an exportStar function to a statement list if it is needed for the file.
+         *
+         * @param statements A statement list.
+         */
+        function addExportStarIfNeeded(statements) {
+            if (!moduleInfo.hasExportStarsToExportValues) {
+                return;
+            }
+            // when resolving exports local exported entries/indirect exported entries in the module
+            // should always win over entries with similar names that were added via star exports
+            // to support this we store names of local/indirect exported entries in a set.
+            // this set is used to filter names brought by star expors.
+            // local names set should only be added if we have anything exported
+            if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) {
+                // no exported declarations (export var ...) or export specifiers (export {x})
+                // check if we have any non star export declarations.
+                var hasExportDeclarationWithExportClause = false;
+                for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) {
+                    var externalImport = _a[_i];
+                    if (externalImport.kind === 244 /* ExportDeclaration */ && externalImport.exportClause) {
+                        hasExportDeclarationWithExportClause = true;
+                        break;
+                    }
+                }
+                if (!hasExportDeclarationWithExportClause) {
+                    // we still need to emit exportStar helper
+                    var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined);
+                    statements.push(exportStarFunction_1);
+                    return exportStarFunction_1.name;
+                }
+            }
+            var exportedNames = [];
+            if (moduleInfo.exportedNames) {
+                for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) {
+                    var exportedLocalName = _c[_b];
+                    if (exportedLocalName.escapedText === "default") {
+                        continue;
+                    }
+                    // write name of exported declaration, i.e 'export var x...'
+                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue()));
+                }
+            }
+            for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) {
+                var externalImport = _e[_d];
+                if (externalImport.kind !== 244 /* ExportDeclaration */) {
+                    continue;
+                }
+                var exportDecl = externalImport;
+                if (!exportDecl.exportClause) {
+                    // export * from ...
+                    continue;
+                }
+                for (var _f = 0, _g = exportDecl.exportClause.elements; _f < _g.length; _f++) {
+                    var element = _g[_f];
+                    // write name of indirectly exported entry, i.e. 'export {x} from ...'
+                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue()));
+                }
+            }
+            var exportedNamesStorageRef = ts.createUniqueName("exportedNames");
+            statements.push(ts.createVariableStatement(
+            /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                ts.createVariableDeclaration(exportedNamesStorageRef, 
+                /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true))
+            ])));
+            var exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
+            statements.push(exportStarFunction);
+            return exportStarFunction.name;
+        }
+        /**
+         * Creates an exportStar function for the file, with an optional set of excluded local
+         * names.
+         *
+         * @param localNames An optional reference to an object containing a set of excluded local
+         * names.
+         */
+        function createExportStarFunction(localNames) {
+            var exportStarFunction = ts.createUniqueName("exportStar");
+            var m = ts.createIdentifier("m");
+            var n = ts.createIdentifier("n");
+            var exports = ts.createIdentifier("exports");
+            var condition = ts.createStrictInequality(n, ts.createLiteral("default"));
+            if (localNames) {
+                condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), 
+                /*typeArguments*/ undefined, [n])));
+            }
+            return ts.createFunctionDeclaration(
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, 
+            /*asteriskToken*/ undefined, exportStarFunction, 
+            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], 
+            /*type*/ undefined, ts.createBlock([
+                ts.createVariableStatement(
+                /*modifiers*/ undefined, ts.createVariableDeclarationList([
+                    ts.createVariableDeclaration(exports, 
+                    /*type*/ undefined, ts.createObjectLiteral([]))
+                ])),
+                ts.createForIn(ts.createVariableDeclarationList([
+                    ts.createVariableDeclaration(n, /*type*/ undefined)
+                ]), m, ts.createBlock([
+                    ts.setEmitFlags(ts.createIf(condition, ts.createStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */)
+                ])),
+                ts.createStatement(ts.createCall(exportFunction, 
+                /*typeArguments*/ undefined, [exports]))
+            ], /*multiline*/ true));
+        }
+        /**
+         * Creates an array setter callbacks for each dependency group.
+         *
+         * @param exportStarFunction A reference to an exportStarFunction for the file.
+         * @param dependencyGroups An array of grouped dependencies.
+         */
+        function createSettersArray(exportStarFunction, dependencyGroups) {
+            var setters = [];
+            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
+                var group = dependencyGroups_1[_i];
+                // derive a unique name for parameter from the first named entry in the group
+                var localName = ts.forEach(group.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); });
+                var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName("");
+                var statements = [];
+                for (var _a = 0, _b = group.externalImports; _a < _b.length; _a++) {
+                    var entry = _b[_a];
+                    var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile);
+                    switch (entry.kind) {
+                        case 238 /* ImportDeclaration */:
+                            if (!entry.importClause) {
+                                // 'import "..."' case
+                                // module is imported only for side-effects, no emit required
+                                break;
+                            }
+                        // falls through
+                        case 237 /* ImportEqualsDeclaration */:
+                            ts.Debug.assert(importVariableName !== undefined);
+                            // save import into the local
+                            statements.push(ts.createStatement(ts.createAssignment(importVariableName, parameterName)));
+                            break;
+                        case 244 /* ExportDeclaration */:
+                            ts.Debug.assert(importVariableName !== undefined);
+                            if (entry.exportClause) {
+                                //  export {a, b as c} from 'foo'
+                                //
+                                // emit as:
+                                //
+                                //  exports_({
+                                //     "a": _["a"],
+                                //     "c": _["b"]
+                                //  });
+                                var properties = [];
+                                for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) {
+                                    var e = _d[_c];
+                                    properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name)))));
+                                }
+                                statements.push(ts.createStatement(ts.createCall(exportFunction, 
+                                /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)])));
+                            }
+                            else {
+                                //  export * from 'foo'
+                                //
+                                // emit as:
+                                //
+                                //  exportStar(foo_1_1);
+                                statements.push(ts.createStatement(ts.createCall(exportStarFunction, 
+                                /*typeArguments*/ undefined, [parameterName])));
+                            }
+                            break;
+                    }
+                }
+                setters.push(ts.createFunctionExpression(
+                /*modifiers*/ undefined, 
+                /*asteriskToken*/ undefined, 
+                /*name*/ undefined, 
+                /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
+                /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true)));
+            }
+            return ts.createArrayLiteral(setters, /*multiLine*/ true);
+        }
+        //
+        // Top-level Source Element Visitors
+        //
+        /**
+         * Visit source elements at the top-level of a module.
+         *
+         * @param node The node to visit.
+         */
+        function sourceElementVisitor(node) {
+            switch (node.kind) {
+                case 238 /* ImportDeclaration */:
+                    return visitImportDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return visitImportEqualsDeclaration(node);
+                case 244 /* ExportDeclaration */:
+                    // ExportDeclarations are elided as they are handled via
+                    // `appendExportsOfDeclaration`.
+                    return undefined;
+                case 243 /* ExportAssignment */:
+                    return visitExportAssignment(node);
+                default:
+                    return nestedElementVisitor(node);
+            }
+        }
+        /**
+         * Visits an ImportDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitImportDeclaration(node) {
+            var statements;
+            if (node.importClause) {
+                hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfImportDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits an ImportEqualsDeclaration node.
+         *
+         * @param node The node to visit.
+         */
+        function visitImportEqualsDeclaration(node) {
+            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
+            var statements;
+            hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile));
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfImportEqualsDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits an ExportAssignment node.
+         *
+         * @param node The node to visit.
+         */
+        function visitExportAssignment(node) {
+            if (node.isExportEquals) {
+                // Elide `export=` as it is illegal in a SystemJS module.
+                return undefined;
+            }
+            var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression);
+            var original = node.original;
+            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true);
+            }
+            else {
+                return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true);
+            }
+        }
+        /**
+         * Visits a FunctionDeclaration, hoisting it to the outer module body function.
+         *
+         * @param node The node to visit.
+         */
+        function visitFunctionDeclaration(node) {
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
+                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), 
+                /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock)));
+            }
+            else {
+                hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context));
+            }
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
+            }
+            else {
+                hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
+            }
+            return undefined;
+        }
+        /**
+         * Visits a ClassDeclaration, hoisting its name to the outer module body function.
+         *
+         * @param node The node to visit.
+         */
+        function visitClassDeclaration(node) {
+            var statements;
+            // Hoist the name of the class declaration to the outer module body function.
+            var name = ts.getLocalName(node);
+            hoistVariableDeclaration(name);
+            // Rewrite the class declaration into an assignment of a class expression.
+            statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression(
+            /*modifiers*/ undefined, node.name, 
+            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node));
+            if (hasAssociatedEndOfDeclarationMarker(node)) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
+            }
+            else {
+                statements = appendExportsOfHoistedDeclaration(statements, node);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Visits a variable statement, hoisting declared names to the top-level module body.
+         * Each declaration is rewritten into an assignment expression.
+         *
+         * @param node The node to visit.
+         */
+        function visitVariableStatement(node) {
+            if (!shouldHoistVariableDeclarationList(node.declarationList)) {
+                return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement);
+            }
+            var expressions;
+            var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */);
+            var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
+            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                var variable = _a[_i];
+                if (variable.initializer) {
+                    expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration));
+                }
+                else {
+                    hoistBindingElement(variable);
+                }
+            }
+            var statements;
+            if (expressions) {
+                statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node));
+            }
+            if (isMarkedDeclaration) {
+                // Defer exports until we encounter an EndOfDeclarationMarker node
+                var id = ts.getOriginalNodeId(node);
+                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
+            }
+            else {
+                statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
+            }
+            return ts.singleOrMany(statements);
+        }
+        /**
+         * Hoists the declared names of a VariableDeclaration or BindingElement.
+         *
+         * @param node The declaration to hoist.
+         */
+        function hoistBindingElement(node) {
+            if (ts.isBindingPattern(node.name)) {
+                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        hoistBindingElement(element);
+                    }
+                }
+            }
+            else {
+                hoistVariableDeclaration(ts.getSynthesizedClone(node.name));
+            }
+        }
+        /**
+         * Determines whether a VariableDeclarationList should be hoisted.
+         *
+         * @param node The node to test.
+         */
+        function shouldHoistVariableDeclarationList(node) {
+            // hoist only non-block scoped declarations or block scoped declarations parented by source file
+            return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0
+                && (enclosingBlockScopedContainer.kind === 265 /* SourceFile */
+                    || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0);
+        }
+        /**
+         * Transform an initialized variable declaration into an expression.
+         *
+         * @param node The node to transform.
+         * @param isExportedDeclaration A value indicating whether the variable is exported.
+         */
+        function transformInitializedVariable(node, isExportedDeclaration) {
+            var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
+            return ts.isBindingPattern(node.name)
+                ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
+                /*needsValue*/ false, createAssignment)
+                : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name;
+        }
+        /**
+         * Creates an assignment expression for an exported variable declaration.
+         *
+         * @param name The name of the variable.
+         * @param value The value of the variable's initializer.
+         * @param location The source map location for the assignment.
+         */
+        function createExportedVariableAssignment(name, value, location) {
+            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true);
+        }
+        /**
+         * Creates an assignment expression for a non-exported variable declaration.
+         *
+         * @param name The name of the variable.
+         * @param value The value of the variable's initializer.
+         * @param location The source map location for the assignment.
+         */
+        function createNonExportedVariableAssignment(name, value, location) {
+            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false);
+        }
+        /**
+         * Creates an assignment expression for a variable declaration.
+         *
+         * @param name The name of the variable.
+         * @param value The value of the variable's initializer.
+         * @param location The source map location for the assignment.
+         * @param isExportedDeclaration A value indicating whether the variable is exported.
+         */
+        function createVariableAssignment(name, value, location, isExportedDeclaration) {
+            hoistVariableDeclaration(ts.getSynthesizedClone(name));
+            return isExportedDeclaration
+                ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)))
+                : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location));
+        }
+        /**
+         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
+         * and transformed declaration.
+         *
+         * @param node The node to visit.
+         */
+        function visitMergeDeclarationMarker(node) {
+            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
+            // declaration we do not emit a leading variable declaration. To preserve the
+            // begin/end semantics of the declararation and to properly handle exports
+            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
+            //
+            // To balance the declaration, we defer the exports of the elided variable
+            // statement until we visit this declaration's `EndOfDeclarationMarker`.
+            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 208 /* VariableStatement */) {
+                var id = ts.getOriginalNodeId(node);
+                var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */);
+                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration);
+            }
+            return node;
+        }
+        /**
+         * Determines whether a node has an associated EndOfDeclarationMarker.
+         *
+         * @param node The node to test.
+         */
+        function hasAssociatedEndOfDeclarationMarker(node) {
+            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
+        }
+        /**
+         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
+         * declaration.
+         *
+         * @param node The node to visit.
+         */
+        function visitEndOfDeclarationMarker(node) {
+            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
+            // end of the transformed declaration. We use this marker to emit any deferred exports
+            // of the declaration.
+            var id = ts.getOriginalNodeId(node);
+            var statements = deferredExports[id];
+            if (statements) {
+                delete deferredExports[id];
+                return ts.append(statements, node);
+            }
+            return node;
+        }
+        /**
+         * Appends the exports of an ImportDeclaration to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfImportDeclaration(statements, decl) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            var importClause = decl.importClause;
+            if (!importClause) {
+                return statements;
+            }
+            if (importClause.name) {
+                statements = appendExportsOfDeclaration(statements, importClause);
+            }
+            var namedBindings = importClause.namedBindings;
+            if (namedBindings) {
+                switch (namedBindings.kind) {
+                    case 240 /* NamespaceImport */:
+                        statements = appendExportsOfDeclaration(statements, namedBindings);
+                        break;
+                    case 241 /* NamedImports */:
+                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
+                            var importBinding = _a[_i];
+                            statements = appendExportsOfDeclaration(statements, importBinding);
+                        }
+                        break;
+                }
+            }
+            return statements;
+        }
+        /**
+         * Appends the export of an ImportEqualsDeclaration to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfImportEqualsDeclaration(statements, decl) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            return appendExportsOfDeclaration(statements, decl);
+        }
+        /**
+         * Appends the exports of a VariableStatement to a statement list, returning the statement
+         * list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param node The VariableStatement whose exports are to be recorded.
+         * @param exportSelf A value indicating whether to also export each VariableDeclaration of
+         * `nodes` declaration list.
+         */
+        function appendExportsOfVariableStatement(statements, node, exportSelf) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
+                var decl = _a[_i];
+                if (decl.initializer || exportSelf) {
+                    statements = appendExportsOfBindingElement(statements, decl, exportSelf);
+                }
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
+         * returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         * @param exportSelf A value indicating whether to also export the declaration itself.
+         */
+        function appendExportsOfBindingElement(statements, decl, exportSelf) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            if (ts.isBindingPattern(decl.name)) {
+                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    if (!ts.isOmittedExpression(element)) {
+                        statements = appendExportsOfBindingElement(statements, element, exportSelf);
+                    }
+                }
+            }
+            else if (!ts.isGeneratedIdentifier(decl.name)) {
+                var excludeName = void 0;
+                if (exportSelf) {
+                    statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl));
+                    excludeName = ts.idText(decl.name);
+                }
+                statements = appendExportsOfDeclaration(statements, decl, excludeName);
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
+         * returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration whose exports are to be recorded.
+         */
+        function appendExportsOfHoistedDeclaration(statements, decl) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            var excludeName;
+            if (ts.hasModifier(decl, 1 /* Export */)) {
+                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name;
+                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl));
+                excludeName = ts.getTextOfIdentifierOrLiteral(exportName);
+            }
+            if (decl.name) {
+                statements = appendExportsOfDeclaration(statements, decl, excludeName);
+            }
+            return statements;
+        }
+        /**
+         * Appends the exports of a declaration to a statement list, returning the statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param decl The declaration to export.
+         * @param excludeName An optional name to exclude from exports.
+         */
+        function appendExportsOfDeclaration(statements, decl, excludeName) {
+            if (moduleInfo.exportEquals) {
+                return statements;
+            }
+            var name = ts.getDeclarationName(decl);
+            var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name));
+            if (exportSpecifiers) {
+                for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) {
+                    var exportSpecifier = exportSpecifiers_2[_i];
+                    if (exportSpecifier.name.escapedText !== excludeName) {
+                        statements = appendExportStatement(statements, exportSpecifier.name, name);
+                    }
+                }
+            }
+            return statements;
+        }
+        /**
+         * Appends the down-level representation of an export to a statement list, returning the
+         * statement list.
+         *
+         * @param statements A statement list to which the down-level export statements are to be
+         * appended. If `statements` is `undefined`, a new array is allocated if statements are
+         * appended.
+         * @param exportName The name of the export.
+         * @param expression The expression to export.
+         * @param allowComments Whether to allow comments on the export.
+         */
+        function appendExportStatement(statements, exportName, expression, allowComments) {
+            statements = ts.append(statements, createExportStatement(exportName, expression, allowComments));
+            return statements;
+        }
+        /**
+         * Creates a call to the current file's export function to export a value.
+         *
+         * @param name The bound name of the export.
+         * @param value The exported value.
+         * @param allowComments An optional value indicating whether to emit comments for the statement.
+         */
+        function createExportStatement(name, value, allowComments) {
+            var statement = ts.createStatement(createExportExpression(name, value));
+            ts.startOnNewLine(statement);
+            if (!allowComments) {
+                ts.setEmitFlags(statement, 1536 /* NoComments */);
+            }
+            return statement;
+        }
+        /**
+         * Creates a call to the current file's export function to export a value.
+         *
+         * @param name The bound name of the export.
+         * @param value The exported value.
+         */
+        function createExportExpression(name, value) {
+            var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name;
+            ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */);
+            return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
+        }
+        //
+        // Top-Level or Nested Source Element Visitors
+        //
+        /**
+         * Visit nested elements at the top-level of a module.
+         *
+         * @param node The node to visit.
+         */
+        function nestedElementVisitor(node) {
+            switch (node.kind) {
+                case 208 /* VariableStatement */:
+                    return visitVariableStatement(node);
+                case 228 /* FunctionDeclaration */:
+                    return visitFunctionDeclaration(node);
+                case 229 /* ClassDeclaration */:
+                    return visitClassDeclaration(node);
+                case 214 /* ForStatement */:
+                    return visitForStatement(node);
+                case 215 /* ForInStatement */:
+                    return visitForInStatement(node);
+                case 216 /* ForOfStatement */:
+                    return visitForOfStatement(node);
+                case 212 /* DoStatement */:
+                    return visitDoStatement(node);
+                case 213 /* WhileStatement */:
+                    return visitWhileStatement(node);
+                case 222 /* LabeledStatement */:
+                    return visitLabeledStatement(node);
+                case 220 /* WithStatement */:
+                    return visitWithStatement(node);
+                case 221 /* SwitchStatement */:
+                    return visitSwitchStatement(node);
+                case 235 /* CaseBlock */:
+                    return visitCaseBlock(node);
+                case 257 /* CaseClause */:
+                    return visitCaseClause(node);
+                case 258 /* DefaultClause */:
+                    return visitDefaultClause(node);
+                case 224 /* TryStatement */:
+                    return visitTryStatement(node);
+                case 260 /* CatchClause */:
+                    return visitCatchClause(node);
+                case 207 /* Block */:
+                    return visitBlock(node);
+                case 290 /* MergeDeclarationMarker */:
+                    return visitMergeDeclarationMarker(node);
+                case 291 /* EndOfDeclarationMarker */:
+                    return visitEndOfDeclarationMarker(node);
+                default:
+                    return destructuringAndImportCallVisitor(node);
+            }
+        }
+        /**
+         * Visits the body of a ForStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitForStatement(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.updateFor(node, visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement));
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        /**
+         * Visits the body of a ForInStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitForInStatement(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        /**
+         * Visits the body of a ForOfStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitForOfStatement(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        /**
+         * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or
+         * ForOfStatement.
+         *
+         * @param node The node to test.
+         */
+        function shouldHoistForInitializer(node) {
+            return ts.isVariableDeclarationList(node)
+                && shouldHoistVariableDeclarationList(node);
+        }
+        /**
+         * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement
+         *
+         * @param node The node to visit.
+         */
+        function visitForInitializer(node) {
+            if (!node) {
+                return node;
+            }
+            if (shouldHoistForInitializer(node)) {
+                var expressions = void 0;
+                for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
+                    var variable = _a[_i];
+                    expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
+                    if (!variable.initializer) {
+                        hoistBindingElement(variable);
+                    }
+                }
+                return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression();
+            }
+            else {
+                return ts.visitEachChild(node, nestedElementVisitor, context);
+            }
+        }
+        /**
+         * Visits the body of a DoStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitDoStatement(node) {
+            return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression));
+        }
+        /**
+         * Visits the body of a WhileStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitWhileStatement(node) {
+            return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
+        }
+        /**
+         * Visits the body of a LabeledStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitLabeledStatement(node) {
+            return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
+        }
+        /**
+         * Visits the body of a WithStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitWithStatement(node) {
+            return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
+        }
+        /**
+         * Visits the body of a SwitchStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitSwitchStatement(node) {
+            return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock));
+        }
+        /**
+         * Visits the body of a CaseBlock to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitCaseBlock(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause));
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        /**
+         * Visits the body of a CaseClause to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitCaseClause(node) {
+            return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement));
+        }
+        /**
+         * Visits the body of a DefaultClause to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitDefaultClause(node) {
+            return ts.visitEachChild(node, nestedElementVisitor, context);
+        }
+        /**
+         * Visits the body of a TryStatement to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitTryStatement(node) {
+            return ts.visitEachChild(node, nestedElementVisitor, context);
+        }
+        /**
+         * Visits the body of a CatchClause to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitCatchClause(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock));
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        /**
+         * Visits the body of a Block to hoist declarations.
+         *
+         * @param node The node to visit.
+         */
+        function visitBlock(node) {
+            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
+            enclosingBlockScopedContainer = node;
+            node = ts.visitEachChild(node, nestedElementVisitor, context);
+            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
+            return node;
+        }
+        //
+        // Destructuring Assignment Visitors
+        //
+        /**
+         * Visit nodes to flatten destructuring assignments to exported symbols.
+         *
+         * @param node The node to visit.
+         */
+        function destructuringAndImportCallVisitor(node) {
+            if (node.transformFlags & 1024 /* DestructuringAssignment */
+                && node.kind === 194 /* BinaryExpression */) {
+                return visitDestructuringAssignment(node);
+            }
+            else if (ts.isImportCall(node)) {
+                return visitImportCallExpression(node);
+            }
+            else if ((node.transformFlags & 2048 /* ContainsDestructuringAssignment */) || (node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
+                return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
+            }
+            else {
+                return node;
+            }
+        }
+        function visitImportCallExpression(node) {
+            // import("./blah")
+            // emit as
+            // System.register([], function (_export, _context) {
+            //     return {
+            //         setters: [],
+            //         execute: () => {
+            //             _context.import('./blah');
+            //         }
+            //     };
+            // });
+            return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), 
+            /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []);
+        }
+        /**
+         * Visits a DestructuringAssignment to flatten destructuring to exported symbols.
+         *
+         * @param node The node to visit.
+         */
+        function visitDestructuringAssignment(node) {
+            if (hasExportedReferenceInDestructuringTarget(node.left)) {
+                return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
+                /*needsValue*/ true);
+            }
+            return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
+        }
+        /**
+         * Determines whether the target of a destructuring assigment refers to an exported symbol.
+         *
+         * @param node The destructuring target.
+         */
+        function hasExportedReferenceInDestructuringTarget(node) {
+            if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
+                return hasExportedReferenceInDestructuringTarget(node.left);
+            }
+            else if (ts.isSpreadElement(node)) {
+                return hasExportedReferenceInDestructuringTarget(node.expression);
+            }
+            else if (ts.isObjectLiteralExpression(node)) {
+                return ts.some(node.properties, hasExportedReferenceInDestructuringTarget);
+            }
+            else if (ts.isArrayLiteralExpression(node)) {
+                return ts.some(node.elements, hasExportedReferenceInDestructuringTarget);
+            }
+            else if (ts.isShorthandPropertyAssignment(node)) {
+                return hasExportedReferenceInDestructuringTarget(node.name);
+            }
+            else if (ts.isPropertyAssignment(node)) {
+                return hasExportedReferenceInDestructuringTarget(node.initializer);
+            }
+            else if (ts.isIdentifier(node)) {
+                var container = resolver.getReferencedExportContainer(node);
+                return container !== undefined && container.kind === 265 /* SourceFile */;
+            }
+            else {
+                return false;
+            }
+        }
+        //
+        // Modifier Visitors
+        //
+        /**
+         * Visit nodes to elide module-specific modifiers.
+         *
+         * @param node The node to visit.
+         */
+        function modifierVisitor(node) {
+            switch (node.kind) {
+                case 84 /* ExportKeyword */:
+                case 79 /* DefaultKeyword */:
+                    return undefined;
+            }
+            return node;
+        }
+        //
+        // Emit Notification
+        //
+        /**
+         * Hook for node emit notifications.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emitCallback A callback used to emit the node in the printer.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            if (node.kind === 265 /* SourceFile */) {
+                var id = ts.getOriginalNodeId(node);
+                currentSourceFile = node;
+                moduleInfo = moduleInfoMap[id];
+                exportFunction = exportFunctionsMap[id];
+                noSubstitution = noSubstitutionMap[id];
+                if (noSubstitution) {
+                    delete noSubstitutionMap[id];
+                }
+                previousOnEmitNode(hint, node, emitCallback);
+                currentSourceFile = undefined;
+                moduleInfo = undefined;
+                exportFunction = undefined;
+                noSubstitution = undefined;
+            }
+            else {
+                previousOnEmitNode(hint, node, emitCallback);
+            }
+        }
+        //
+        // Substitutions
+        //
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (isSubstitutionPrevented(node)) {
+                return node;
+            }
+            if (hint === 1 /* Expression */) {
+                return substituteExpression(node);
+            }
+            return node;
+        }
+        /**
+         * Substitute the expression, if necessary.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteExpression(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return substituteExpressionIdentifier(node);
+                case 194 /* BinaryExpression */:
+                    return substituteBinaryExpression(node);
+                case 192 /* PrefixUnaryExpression */:
+                case 193 /* PostfixUnaryExpression */:
+                    return substituteUnaryExpression(node);
+            }
+            return node;
+        }
+        /**
+         * Substitution for an Identifier expression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteExpressionIdentifier(node) {
+            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
+                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
+                if (externalHelpersModuleName) {
+                    return ts.createPropertyAccess(externalHelpersModuleName, node);
+                }
+                return node;
+            }
+            // When we see an identifier in an expression position that
+            // points to an imported symbol, we should substitute a qualified
+            // reference to the imported symbol if one is needed.
+            //
+            // - We do not substitute generated identifiers for any reason.
+            // - We do not substitute identifiers tagged with the LocalName flag.
+            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
+                var importDeclaration = resolver.getReferencedImportDeclaration(node);
+                if (importDeclaration) {
+                    if (ts.isImportClause(importDeclaration)) {
+                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
+                        /*location*/ node);
+                    }
+                    else if (ts.isImportSpecifier(importDeclaration)) {
+                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), 
+                        /*location*/ node);
+                    }
+                }
+            }
+            return node;
+        }
+        /**
+         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteBinaryExpression(node) {
+            // When we see an assignment expression whose left-hand side is an exported symbol,
+            // we should ensure all exports of that symbol are updated with the correct value.
+            //
+            // - We do not substitute generated identifiers for any reason.
+            // - We do not substitute identifiers tagged with the LocalName flag.
+            // - We do not substitute identifiers that were originally the name of an enum or
+            //   namespace due to how they are transformed in TypeScript.
+            // - We only substitute identifiers that are exported at the top level.
+            if (ts.isAssignmentOperator(node.operatorToken.kind)
+                && ts.isIdentifier(node.left)
+                && !ts.isGeneratedIdentifier(node.left)
+                && !ts.isLocalName(node.left)
+                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
+                var exportedNames = getExports(node.left);
+                if (exportedNames) {
+                    // For each additional export of the declaration, apply an export assignment.
+                    var expression = node;
+                    for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) {
+                        var exportName = exportedNames_3[_i];
+                        expression = createExportExpression(exportName, preventSubstitution(expression));
+                    }
+                    return expression;
+                }
+            }
+            return node;
+        }
+        /**
+         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
+         *
+         * @param node The node to substitute.
+         */
+        function substituteUnaryExpression(node) {
+            // When we see a prefix or postfix increment expression whose operand is an exported
+            // symbol, we should ensure all exports of that symbol are updated with the correct
+            // value.
+            //
+            // - We do not substitute generated identifiers for any reason.
+            // - We do not substitute identifiers tagged with the LocalName flag.
+            // - We do not substitute identifiers that were originally the name of an enum or
+            //   namespace due to how they are transformed in TypeScript.
+            // - We only substitute identifiers that are exported at the top level.
+            if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */)
+                && ts.isIdentifier(node.operand)
+                && !ts.isGeneratedIdentifier(node.operand)
+                && !ts.isLocalName(node.operand)
+                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
+                var exportedNames = getExports(node.operand);
+                if (exportedNames) {
+                    var expression = node.kind === 193 /* PostfixUnaryExpression */
+                        ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node)
+                        : node;
+                    for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) {
+                        var exportName = exportedNames_4[_i];
+                        expression = createExportExpression(exportName, preventSubstitution(expression));
+                    }
+                    if (node.kind === 193 /* PostfixUnaryExpression */) {
+                        expression = node.operator === 43 /* PlusPlusToken */
+                            ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1))
+                            : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1));
+                    }
+                    return expression;
+                }
+            }
+            return node;
+        }
+        /**
+         * Gets the exports of a name.
+         *
+         * @param name The name.
+         */
+        function getExports(name) {
+            var exportedNames;
+            if (!ts.isGeneratedIdentifier(name)) {
+                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
+                    || resolver.getReferencedValueDeclaration(name);
+                if (valueDeclaration) {
+                    var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false);
+                    if (exportContainer && exportContainer.kind === 265 /* SourceFile */) {
+                        exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration));
+                    }
+                    exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]);
+                }
+            }
+            return exportedNames;
+        }
+        /**
+         * Prevent substitution of a node for this transformer.
+         *
+         * @param node The node which should not be substituted.
+         */
+        function preventSubstitution(node) {
+            if (noSubstitution === undefined)
+                noSubstitution = [];
+            noSubstitution[ts.getNodeId(node)] = true;
+            return node;
+        }
+        /**
+         * Determines whether a node should not be substituted.
+         *
+         * @param node The node to test.
+         */
+        function isSubstitutionPrevented(node) {
+            return noSubstitution && node.id && noSubstitution[node.id];
+        }
+    }
+    ts.transformSystemModule = transformSystemModule;
+})(ts || (ts = {}));
+/// <reference path="../../factory.ts" />
+/// <reference path="../../visitor.ts" />
+/*@internal*/
+var ts;
+(function (ts) {
+    function transformES2015Module(context) {
+        var compilerOptions = context.getCompilerOptions();
+        var previousOnEmitNode = context.onEmitNode;
+        var previousOnSubstituteNode = context.onSubstituteNode;
+        context.onEmitNode = onEmitNode;
+        context.onSubstituteNode = onSubstituteNode;
+        context.enableEmitNotification(265 /* SourceFile */);
+        context.enableSubstitution(71 /* Identifier */);
+        var currentSourceFile;
+        return transformSourceFile;
+        function transformSourceFile(node) {
+            if (node.isDeclarationFile) {
+                return node;
+            }
+            if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
+                var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
+                if (externalHelpersModuleName) {
+                    var statements = [];
+                    var statementOffset = ts.addPrologue(statements, node.statements);
+                    ts.append(statements, ts.createImportDeclaration(
+                    /*decorators*/ undefined, 
+                    /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText)));
+                    ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
+                    return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
+                }
+                else {
+                    return ts.visitEachChild(node, visitor, context);
+                }
+            }
+            return node;
+        }
+        function visitor(node) {
+            switch (node.kind) {
+                case 237 /* ImportEqualsDeclaration */:
+                    // Elide `import=` as it is not legal with --module ES6
+                    return undefined;
+                case 243 /* ExportAssignment */:
+                    return visitExportAssignment(node);
+            }
+            return node;
+        }
+        function visitExportAssignment(node) {
+            // Elide `export=` as it is not legal with --module ES6
+            return node.isExportEquals ? undefined : node;
+        }
+        //
+        // Emit Notification
+        //
+        /**
+         * Hook for node emit.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emit A callback used to emit the node in the printer.
+         */
+        function onEmitNode(hint, node, emitCallback) {
+            if (ts.isSourceFile(node)) {
+                currentSourceFile = node;
+                previousOnEmitNode(hint, node, emitCallback);
+                currentSourceFile = undefined;
+            }
+            else {
+                previousOnEmitNode(hint, node, emitCallback);
+            }
+        }
+        //
+        // Substitutions
+        //
+        /**
+         * Hooks node substitutions.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to substitute.
+         */
+        function onSubstituteNode(hint, node) {
+            node = previousOnSubstituteNode(hint, node);
+            if (ts.isIdentifier(node) && hint === 1 /* Expression */) {
+                return substituteExpressionIdentifier(node);
+            }
+            return node;
+        }
+        function substituteExpressionIdentifier(node) {
+            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
+                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
+                if (externalHelpersModuleName) {
+                    return ts.createPropertyAccess(externalHelpersModuleName, node);
+                }
+            }
+            return node;
+        }
+    }
+    ts.transformES2015Module = transformES2015Module;
+})(ts || (ts = {}));
+/// <reference path="visitor.ts" />
+/// <reference path="transformers/utilities.ts" />
+/// <reference path="transformers/ts.ts" />
+/// <reference path="transformers/jsx.ts" />
+/// <reference path="transformers/esnext.ts" />
+/// <reference path="transformers/es2017.ts" />
+/// <reference path="transformers/es2016.ts" />
+/// <reference path="transformers/es2015.ts" />
+/// <reference path="transformers/generators.ts" />
+/// <reference path="transformers/es5.ts" />
+/// <reference path="transformers/module/module.ts" />
+/// <reference path="transformers/module/system.ts" />
+/// <reference path="transformers/module/es2015.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    function getModuleTransformer(moduleKind) {
+        switch (moduleKind) {
+            case ts.ModuleKind.ESNext:
+            case ts.ModuleKind.ES2015:
+                return ts.transformES2015Module;
+            case ts.ModuleKind.System:
+                return ts.transformSystemModule;
+            default:
+                return ts.transformModule;
+        }
+    }
+    var TransformationState;
+    (function (TransformationState) {
+        TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized";
+        TransformationState[TransformationState["Initialized"] = 1] = "Initialized";
+        TransformationState[TransformationState["Completed"] = 2] = "Completed";
+        TransformationState[TransformationState["Disposed"] = 3] = "Disposed";
+    })(TransformationState || (TransformationState = {}));
+    var SyntaxKindFeatureFlags;
+    (function (SyntaxKindFeatureFlags) {
+        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution";
+        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications";
+    })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {}));
+    function getTransformers(compilerOptions, customTransformers) {
+        var jsx = compilerOptions.jsx;
+        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
+        var moduleKind = ts.getEmitModuleKind(compilerOptions);
+        var transformers = [];
+        ts.addRange(transformers, customTransformers && customTransformers.before);
+        transformers.push(ts.transformTypeScript);
+        if (jsx === 2 /* React */) {
+            transformers.push(ts.transformJsx);
+        }
+        if (languageVersion < 5 /* ESNext */) {
+            transformers.push(ts.transformESNext);
+        }
+        if (languageVersion < 4 /* ES2017 */) {
+            transformers.push(ts.transformES2017);
+        }
+        if (languageVersion < 3 /* ES2016 */) {
+            transformers.push(ts.transformES2016);
+        }
+        if (languageVersion < 2 /* ES2015 */) {
+            transformers.push(ts.transformES2015);
+            transformers.push(ts.transformGenerators);
+        }
+        transformers.push(getModuleTransformer(moduleKind));
+        // The ES5 transformer is last so that it can substitute expressions like `exports.default`
+        // for ES3.
+        if (languageVersion < 1 /* ES5 */) {
+            transformers.push(ts.transformES5);
+        }
+        ts.addRange(transformers, customTransformers && customTransformers.after);
+        return transformers;
+    }
+    ts.getTransformers = getTransformers;
+    /**
+     * Transforms an array of SourceFiles by passing them through each transformer.
+     *
+     * @param resolver The emit resolver provided by the checker.
+     * @param host The emit host object used to interact with the file system.
+     * @param options Compiler options to surface in the `TransformationContext`.
+     * @param nodes An array of nodes to transform.
+     * @param transforms An array of `TransformerFactory` callbacks.
+     * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
+     */
+    function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) {
+        var enabledSyntaxKindFeatures = new Array(292 /* Count */);
+        var lexicalEnvironmentVariableDeclarations;
+        var lexicalEnvironmentFunctionDeclarations;
+        var lexicalEnvironmentVariableDeclarationsStack = [];
+        var lexicalEnvironmentFunctionDeclarationsStack = [];
+        var lexicalEnvironmentStackOffset = 0;
+        var lexicalEnvironmentSuspended = false;
+        var emitHelpers;
+        var onSubstituteNode = function (_, node) { return node; };
+        var onEmitNode = function (hint, node, callback) { return callback(hint, node); };
+        var state = 0 /* Uninitialized */;
+        // The transformation context is provided to each transformer as part of transformer
+        // initialization.
+        var context = {
+            getCompilerOptions: function () { return options; },
+            getEmitResolver: function () { return resolver; },
+            getEmitHost: function () { return host; },
+            startLexicalEnvironment: startLexicalEnvironment,
+            suspendLexicalEnvironment: suspendLexicalEnvironment,
+            resumeLexicalEnvironment: resumeLexicalEnvironment,
+            endLexicalEnvironment: endLexicalEnvironment,
+            hoistVariableDeclaration: hoistVariableDeclaration,
+            hoistFunctionDeclaration: hoistFunctionDeclaration,
+            requestEmitHelper: requestEmitHelper,
+            readEmitHelpers: readEmitHelpers,
+            enableSubstitution: enableSubstitution,
+            enableEmitNotification: enableEmitNotification,
+            isSubstitutionEnabled: isSubstitutionEnabled,
+            isEmitNotificationEnabled: isEmitNotificationEnabled,
+            get onSubstituteNode() { return onSubstituteNode; },
+            set onSubstituteNode(value) {
+                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
+                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
+                onSubstituteNode = value;
+            },
+            get onEmitNode() { return onEmitNode; },
+            set onEmitNode(value) {
+                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
+                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
+                onEmitNode = value;
+            }
+        };
+        // Ensure the parse tree is clean before applying transformations
+        for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
+            var node = nodes_4[_i];
+            ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
+        }
+        ts.performance.mark("beforeTransform");
+        // Chain together and initialize each transformer.
+        var transformation = ts.chain.apply(void 0, transformers)(context);
+        // prevent modification of transformation hooks.
+        state = 1 /* Initialized */;
+        // Transform each node.
+        var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot);
+        // prevent modification of the lexical environment.
+        state = 2 /* Completed */;
+        ts.performance.mark("afterTransform");
+        ts.performance.measure("transformTime", "beforeTransform", "afterTransform");
+        return {
+            transformed: transformed,
+            substituteNode: substituteNode,
+            emitNodeWithNotification: emitNodeWithNotification,
+            dispose: dispose
+        };
+        function transformRoot(node) {
+            return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
+        }
+        /**
+         * Enables expression substitutions in the pretty printer for the provided SyntaxKind.
+         */
+        function enableSubstitution(kind) {
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
+            enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
+        }
+        /**
+         * Determines whether expression substitutions are enabled for the provided node.
+         */
+        function isSubstitutionEnabled(node) {
+            return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0
+                && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0;
+        }
+        /**
+         * Emits a node with possible substitution.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emitCallback The callback used to emit the node or its substitute.
+         */
+        function substituteNode(hint, node) {
+            ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
+            return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
+        }
+        /**
+         * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
+         */
+        function enableEmitNotification(kind) {
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
+            enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
+        }
+        /**
+         * Determines whether before/after emit notifications should be raised in the pretty
+         * printer when it emits a node.
+         */
+        function isEmitNotificationEnabled(node) {
+            return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0
+                || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0;
+        }
+        /**
+         * Emits a node with possible emit notification.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emitCallback The callback used to emit the node.
+         */
+        function emitNodeWithNotification(hint, node, emitCallback) {
+            ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
+            if (node) {
+                if (isEmitNotificationEnabled(node)) {
+                    onEmitNode(hint, node, emitCallback);
+                }
+                else {
+                    emitCallback(hint, node);
+                }
+            }
+        }
+        /**
+         * Records a hoisted variable declaration for the provided name within a lexical environment.
+         */
+        function hoistVariableDeclaration(name) {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */);
+            if (!lexicalEnvironmentVariableDeclarations) {
+                lexicalEnvironmentVariableDeclarations = [decl];
+            }
+            else {
+                lexicalEnvironmentVariableDeclarations.push(decl);
+            }
+        }
+        /**
+         * Records a hoisted function declaration within a lexical environment.
+         */
+        function hoistFunctionDeclaration(func) {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            if (!lexicalEnvironmentFunctionDeclarations) {
+                lexicalEnvironmentFunctionDeclarations = [func];
+            }
+            else {
+                lexicalEnvironmentFunctionDeclarations.push(func);
+            }
+        }
+        /**
+         * Starts a new lexical environment. Any existing hoisted variable or function declarations
+         * are pushed onto a stack, and the related storage variables are reset.
+         */
+        function startLexicalEnvironment() {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
+            // Save the current lexical environment. Rather than resizing the array we adjust the
+            // stack size variable. This allows us to reuse existing array slots we've
+            // already allocated between transformations to avoid allocation and GC overhead during
+            // transformation.
+            lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
+            lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
+            lexicalEnvironmentStackOffset++;
+            lexicalEnvironmentVariableDeclarations = undefined;
+            lexicalEnvironmentFunctionDeclarations = undefined;
+        }
+        /** Suspends the current lexical environment, usually after visiting a parameter list. */
+        function suspendLexicalEnvironment() {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
+            lexicalEnvironmentSuspended = true;
+        }
+        /** Resumes a suspended lexical environment, usually before visiting a function body. */
+        function resumeLexicalEnvironment() {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
+            lexicalEnvironmentSuspended = false;
+        }
+        /**
+         * Ends a lexical environment. The previous set of hoisted declarations are restored and
+         * any hoisted declarations added in this environment are returned.
+         */
+        function endLexicalEnvironment() {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
+            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
+            var statements;
+            if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) {
+                if (lexicalEnvironmentFunctionDeclarations) {
+                    statements = lexicalEnvironmentFunctionDeclarations.slice();
+                }
+                if (lexicalEnvironmentVariableDeclarations) {
+                    var statement = ts.createVariableStatement(
+                    /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations));
+                    if (!statements) {
+                        statements = [statement];
+                    }
+                    else {
+                        statements.push(statement);
+                    }
+                }
+            }
+            // Restore the previous lexical environment.
+            lexicalEnvironmentStackOffset--;
+            lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
+            lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
+            if (lexicalEnvironmentStackOffset === 0) {
+                lexicalEnvironmentVariableDeclarationsStack = [];
+                lexicalEnvironmentFunctionDeclarationsStack = [];
+            }
+            return statements;
+        }
+        function requestEmitHelper(helper) {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
+            ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
+            emitHelpers = ts.append(emitHelpers, helper);
+        }
+        function readEmitHelpers() {
+            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
+            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
+            var helpers = emitHelpers;
+            emitHelpers = undefined;
+            return helpers;
+        }
+        function dispose() {
+            if (state < 3 /* Disposed */) {
+                // Clean up emit nodes on parse tree
+                for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) {
+                    var node = nodes_5[_i];
+                    ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
+                }
+                // Release references to external entries for GC purposes.
+                lexicalEnvironmentVariableDeclarations = undefined;
+                lexicalEnvironmentVariableDeclarationsStack = undefined;
+                lexicalEnvironmentFunctionDeclarations = undefined;
+                lexicalEnvironmentFunctionDeclarationsStack = undefined;
+                onSubstituteNode = undefined;
+                onEmitNode = undefined;
+                emitHelpers = undefined;
+                // Prevent further use of the transformation result.
+                state = 3 /* Disposed */;
+            }
+        }
+    }
+    ts.transformNodes = transformNodes;
+})(ts || (ts = {}));
+/// <reference path="checker.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    // Used for initialize lastEncodedSourceMapSpan and reset lastEncodedSourceMapSpan when updateLastEncodedAndRecordedSpans
+    var defaultLastEncodedSourceMapSpan = {
+        emittedLine: 1,
+        emittedColumn: 1,
+        sourceLine: 1,
+        sourceColumn: 1,
+        sourceIndex: 0
+    };
+    function createSourceMapWriter(host, writer) {
+        var compilerOptions = host.getCompilerOptions();
+        var extendedDiagnostics = compilerOptions.extendedDiagnostics;
+        var currentSource;
+        var currentSourceText;
+        var sourceMapDir; // The directory in which sourcemap will be
+        // Current source map file and its index in the sources list
+        var sourceMapSourceIndex;
+        // Last recorded and encoded spans
+        var lastRecordedSourceMapSpan;
+        var lastEncodedSourceMapSpan;
+        var lastEncodedNameIndex;
+        // Source map data
+        var sourceMapData;
+        var disabled = !(compilerOptions.sourceMap || compilerOptions.inlineSourceMap);
+        return {
+            initialize: initialize,
+            reset: reset,
+            getSourceMapData: function () { return sourceMapData; },
+            setSourceFile: setSourceFile,
+            emitPos: emitPos,
+            emitNodeWithSourceMap: emitNodeWithSourceMap,
+            emitTokenWithSourceMap: emitTokenWithSourceMap,
+            getText: getText,
+            getSourceMappingURL: getSourceMappingURL,
+        };
+        /**
+         * Skips trivia such as comments and white-space that can optionally overriden by the source map source
+         */
+        function skipSourceTrivia(pos) {
+            return currentSource.skipTrivia ? currentSource.skipTrivia(pos) : ts.skipTrivia(currentSourceText, pos);
+        }
+        /**
+         * Initialize the SourceMapWriter for a new output file.
+         *
+         * @param filePath The path to the generated output file.
+         * @param sourceMapFilePath The path to the output source map file.
+         * @param sourceFileOrBundle The input source file or bundle for the program.
+         */
+        function initialize(filePath, sourceMapFilePath, sourceFileOrBundle) {
+            if (disabled) {
+                return;
+            }
+            if (sourceMapData) {
+                reset();
+            }
+            currentSource = undefined;
+            currentSourceText = undefined;
+            // Current source map file and its index in the sources list
+            sourceMapSourceIndex = -1;
+            // Last recorded and encoded spans
+            lastRecordedSourceMapSpan = undefined;
+            lastEncodedSourceMapSpan = defaultLastEncodedSourceMapSpan;
+            lastEncodedNameIndex = 0;
+            // Initialize source map data
+            sourceMapData = {
+                sourceMapFilePath: sourceMapFilePath,
+                jsSourceMappingURL: !compilerOptions.inlineSourceMap ? ts.getBaseFileName(ts.normalizeSlashes(sourceMapFilePath)) : undefined,
+                sourceMapFile: ts.getBaseFileName(ts.normalizeSlashes(filePath)),
+                sourceMapSourceRoot: compilerOptions.sourceRoot || "",
+                sourceMapSources: [],
+                inputSourceFileNames: [],
+                sourceMapNames: [],
+                sourceMapMappings: "",
+                sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined,
+                sourceMapDecodedMappings: []
+            };
+            // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
+            // relative paths of the sources list in the sourcemap
+            sourceMapData.sourceMapSourceRoot = ts.normalizeSlashes(sourceMapData.sourceMapSourceRoot);
+            if (sourceMapData.sourceMapSourceRoot.length && sourceMapData.sourceMapSourceRoot.charCodeAt(sourceMapData.sourceMapSourceRoot.length - 1) !== 47 /* slash */) {
+                sourceMapData.sourceMapSourceRoot += ts.directorySeparator;
+            }
+            if (compilerOptions.mapRoot) {
+                sourceMapDir = ts.normalizeSlashes(compilerOptions.mapRoot);
+                if (sourceFileOrBundle.kind === 265 /* SourceFile */) {
+                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
+                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
+                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir));
+                }
+                if (!ts.isRootedDiskPath(sourceMapDir) && !ts.isUrl(sourceMapDir)) {
+                    // The relative paths are relative to the common directory
+                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
+                    sourceMapData.jsSourceMappingURL = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
+                    ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap
+                    host.getCurrentDirectory(), host.getCanonicalFileName, 
+                    /*isAbsolutePathAnUrl*/ true);
+                }
+                else {
+                    sourceMapData.jsSourceMappingURL = ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL);
+                }
+            }
+            else {
+                sourceMapDir = ts.getDirectoryPath(ts.normalizePath(filePath));
+            }
+        }
+        /**
+         * Reset the SourceMapWriter to an empty state.
+         */
+        function reset() {
+            if (disabled) {
+                return;
+            }
+            currentSource = undefined;
+            sourceMapDir = undefined;
+            sourceMapSourceIndex = undefined;
+            lastRecordedSourceMapSpan = undefined;
+            lastEncodedSourceMapSpan = undefined;
+            lastEncodedNameIndex = undefined;
+            sourceMapData = undefined;
+        }
+        // Encoding for sourcemap span
+        function encodeLastRecordedSourceMapSpan() {
+            if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
+                return;
+            }
+            var prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
+            // Line/Comma delimiters
+            if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
+                // Emit comma to separate the entry
+                if (sourceMapData.sourceMapMappings) {
+                    sourceMapData.sourceMapMappings += ",";
+                }
+            }
+            else {
+                // Emit line delimiters
+                for (var encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
+                    sourceMapData.sourceMapMappings += ";";
+                }
+                prevEncodedEmittedColumn = 1;
+            }
+            // 1. Relative Column 0 based
+            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
+            // 2. Relative sourceIndex
+            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
+            // 3. Relative sourceLine 0 based
+            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
+            // 4. Relative sourceColumn 0 based
+            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
+            // 5. Relative namePosition 0 based
+            if (lastRecordedSourceMapSpan.nameIndex >= 0) {
+                ts.Debug.assert(false, "We do not support name index right now, Make sure to update updateLastEncodedAndRecordedSpans when we start using this");
+                sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
+                lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
+            }
+            lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
+            sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
+        }
+        /**
+         * Emits a mapping.
+         *
+         * If the position is synthetic (undefined or a negative value), no mapping will be
+         * created.
+         *
+         * @param pos The position.
+         */
+        function emitPos(pos) {
+            if (disabled || ts.positionIsSynthesized(pos)) {
+                return;
+            }
+            if (extendedDiagnostics) {
+                ts.performance.mark("beforeSourcemap");
+            }
+            var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSource, pos);
+            // Convert the location to be one-based.
+            sourceLinePos.line++;
+            sourceLinePos.character++;
+            var emittedLine = writer.getLine();
+            var emittedColumn = writer.getColumn();
+            // If this location wasn't recorded or the location in source is going backwards, record the span
+            if (!lastRecordedSourceMapSpan ||
+                lastRecordedSourceMapSpan.emittedLine !== emittedLine ||
+                lastRecordedSourceMapSpan.emittedColumn !== emittedColumn ||
+                (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
+                    (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
+                        (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
+                // Encode the last recordedSpan before assigning new
+                encodeLastRecordedSourceMapSpan();
+                // New span
+                lastRecordedSourceMapSpan = {
+                    emittedLine: emittedLine,
+                    emittedColumn: emittedColumn,
+                    sourceLine: sourceLinePos.line,
+                    sourceColumn: sourceLinePos.character,
+                    sourceIndex: sourceMapSourceIndex
+                };
+            }
+            else {
+                // Take the new pos instead since there is no change in emittedLine and column since last location
+                lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line;
+                lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character;
+                lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex;
+            }
+            if (extendedDiagnostics) {
+                ts.performance.mark("afterSourcemap");
+                ts.performance.measure("Source Map", "beforeSourcemap", "afterSourcemap");
+            }
+        }
+        /**
+         * Emits a node with possible leading and trailing source maps.
+         *
+         * @param hint A hint as to the intended usage of the node.
+         * @param node The node to emit.
+         * @param emitCallback The callback used to emit the node.
+         */
+        function emitNodeWithSourceMap(hint, node, emitCallback) {
+            if (disabled) {
+                return emitCallback(hint, node);
+            }
+            if (node) {
+                var emitNode = node.emitNode;
+                var emitFlags = emitNode && emitNode.flags;
+                var range = emitNode && emitNode.sourceMapRange;
+                var _a = range || node, pos = _a.pos, end = _a.end;
+                var source = range && range.source;
+                var oldSource = currentSource;
+                if (source === oldSource)
+                    source = undefined;
+                if (source)
+                    setSourceFile(source);
+                if (node.kind !== 287 /* NotEmittedStatement */
+                    && (emitFlags & 16 /* NoLeadingSourceMap */) === 0
+                    && pos >= 0) {
+                    emitPos(skipSourceTrivia(pos));
+                }
+                if (source)
+                    setSourceFile(oldSource);
+                if (emitFlags & 64 /* NoNestedSourceMaps */) {
+                    disabled = true;
+                    emitCallback(hint, node);
+                    disabled = false;
+                }
+                else {
+                    emitCallback(hint, node);
+                }
+                if (source)
+                    setSourceFile(source);
+                if (node.kind !== 287 /* NotEmittedStatement */
+                    && (emitFlags & 32 /* NoTrailingSourceMap */) === 0
+                    && end >= 0) {
+                    emitPos(end);
+                }
+                if (source)
+                    setSourceFile(oldSource);
+            }
+        }
+        /**
+         * Emits a token of a node with possible leading and trailing source maps.
+         *
+         * @param node The node containing the token.
+         * @param token The token to emit.
+         * @param tokenStartPos The start pos of the token.
+         * @param emitCallback The callback used to emit the token.
+         */
+        function emitTokenWithSourceMap(node, token, tokenPos, emitCallback) {
+            if (disabled) {
+                return emitCallback(token, tokenPos);
+            }
+            var emitNode = node && node.emitNode;
+            var emitFlags = emitNode && emitNode.flags;
+            var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
+            tokenPos = skipSourceTrivia(range ? range.pos : tokenPos);
+            if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
+                emitPos(tokenPos);
+            }
+            tokenPos = emitCallback(token, tokenPos);
+            if (range)
+                tokenPos = range.end;
+            if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
+                emitPos(tokenPos);
+            }
+            return tokenPos;
+        }
+        /**
+         * Set the current source file.
+         *
+         * @param sourceFile The source file.
+         */
+        function setSourceFile(sourceFile) {
+            if (disabled) {
+                return;
+            }
+            currentSource = sourceFile;
+            currentSourceText = currentSource.text;
+            // Add the file to tsFilePaths
+            // If sourceroot option: Use the relative path corresponding to the common directory path
+            // otherwise source locations relative to map file location
+            var sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
+            var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, currentSource.fileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
+            /*isAbsolutePathAnUrl*/ true);
+            sourceMapSourceIndex = ts.indexOf(sourceMapData.sourceMapSources, source);
+            if (sourceMapSourceIndex === -1) {
+                sourceMapSourceIndex = sourceMapData.sourceMapSources.length;
+                sourceMapData.sourceMapSources.push(source);
+                // The one that can be used from program to get the actual source file
+                sourceMapData.inputSourceFileNames.push(currentSource.fileName);
+                if (compilerOptions.inlineSources) {
+                    sourceMapData.sourceMapSourcesContent.push(currentSource.text);
+                }
+            }
+        }
+        /**
+         * Gets the text for the source map.
+         */
+        function getText() {
+            if (disabled) {
+                return;
+            }
+            encodeLastRecordedSourceMapSpan();
+            return JSON.stringify({
+                version: 3,
+                file: sourceMapData.sourceMapFile,
+                sourceRoot: sourceMapData.sourceMapSourceRoot,
+                sources: sourceMapData.sourceMapSources,
+                names: sourceMapData.sourceMapNames,
+                mappings: sourceMapData.sourceMapMappings,
+                sourcesContent: sourceMapData.sourceMapSourcesContent,
+            });
+        }
+        /**
+         * Gets the SourceMappingURL for the source map.
+         */
+        function getSourceMappingURL() {
+            if (disabled) {
+                return;
+            }
+            if (compilerOptions.inlineSourceMap) {
+                // Encode the sourceMap into the sourceMap url
+                var base64SourceMapText = ts.convertToBase64(getText());
+                return sourceMapData.jsSourceMappingURL = "data:application/json;base64," + base64SourceMapText;
+            }
+            else {
+                return sourceMapData.jsSourceMappingURL;
+            }
+        }
+    }
+    ts.createSourceMapWriter = createSourceMapWriter;
+    var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    function base64FormatEncode(inValue) {
+        if (inValue < 64) {
+            return base64Chars.charAt(inValue);
+        }
+        throw TypeError(inValue + ": not a 64 based value");
+    }
+    function base64VLQFormatEncode(inValue) {
+        // Add a new least significant bit that has the sign of the value.
+        // if negative number the least significant bit that gets added to the number has value 1
+        // else least significant bit value that gets added is 0
+        // eg. -1 changes to binary : 01 [1] => 3
+        //     +1 changes to binary : 01 [0] => 2
+        if (inValue < 0) {
+            inValue = ((-inValue) << 1) + 1;
+        }
+        else {
+            inValue = inValue << 1;
+        }
+        // Encode 5 bits at a time starting from least significant bits
+        var encodedStr = "";
+        do {
+            var currentDigit = inValue & 31; // 11111
+            inValue = inValue >> 5;
+            if (inValue > 0) {
+                // There are still more digits to decode, set the msb (6th bit)
+                currentDigit = currentDigit | 32;
+            }
+            encodedStr = encodedStr + base64FormatEncode(currentDigit);
+        } while (inValue > 0);
+        return encodedStr;
+    }
+})(ts || (ts = {}));
+/// <reference path="sourcemap.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    function createCommentWriter(printerOptions, emitPos) {
+        var extendedDiagnostics = printerOptions.extendedDiagnostics;
+        var newLine = ts.getNewLineCharacter(printerOptions);
+        var writer;
+        var containerPos = -1;
+        var containerEnd = -1;
+        var declarationListContainerEnd = -1;
+        var currentSourceFile;
+        var currentText;
+        var currentLineMap;
+        var detachedCommentsInfo;
+        var hasWrittenComment = false;
+        var disabled = printerOptions.removeComments;
+        return {
+            reset: reset,
+            setWriter: setWriter,
+            setSourceFile: setSourceFile,
+            emitNodeWithComments: emitNodeWithComments,
+            emitBodyWithDetachedComments: emitBodyWithDetachedComments,
+            emitTrailingCommentsOfPosition: emitTrailingCommentsOfPosition,
+            emitLeadingCommentsOfPosition: emitLeadingCommentsOfPosition,
+        };
+        function emitNodeWithComments(hint, node, emitCallback) {
+            if (disabled) {
+                emitCallback(hint, node);
+                return;
+            }
+            if (node) {
+                hasWrittenComment = false;
+                var emitNode = node.emitNode;
+                var emitFlags = emitNode && emitNode.flags;
+                var _a = emitNode && emitNode.commentRange || node, pos = _a.pos, end = _a.end;
+                if ((pos < 0 && end < 0) || (pos === end)) {
+                    // Both pos and end are synthesized, so just emit the node without comments.
+                    emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
+                }
+                else {
+                    if (extendedDiagnostics) {
+                        ts.performance.mark("preEmitNodeWithComment");
+                    }
+                    var isEmittedNode = node.kind !== 287 /* NotEmittedStatement */;
+                    // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
+                    // It is expensive to walk entire tree just to set one kind of node to have no comments.
+                    var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 10 /* JsxText */;
+                    var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 10 /* JsxText */;
+                    // Emit leading comments if the position is not synthesized and the node
+                    // has not opted out from emitting leading comments.
+                    if (!skipLeadingComments) {
+                        emitLeadingComments(pos, isEmittedNode);
+                    }
+                    // Save current container state on the stack.
+                    var savedContainerPos = containerPos;
+                    var savedContainerEnd = containerEnd;
+                    var savedDeclarationListContainerEnd = declarationListContainerEnd;
+                    if (!skipLeadingComments) {
+                        containerPos = pos;
+                    }
+                    if (!skipTrailingComments) {
+                        containerEnd = end;
+                        // To avoid invalid comment emit in a down-level binding pattern, we
+                        // keep track of the last declaration list container's end
+                        if (node.kind === 227 /* VariableDeclarationList */) {
+                            declarationListContainerEnd = end;
+                        }
+                    }
+                    if (extendedDiagnostics) {
+                        ts.performance.measure("commentTime", "preEmitNodeWithComment");
+                    }
+                    emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
+                    if (extendedDiagnostics) {
+                        ts.performance.mark("postEmitNodeWithComment");
+                    }
+                    // Restore previous container state.
+                    containerPos = savedContainerPos;
+                    containerEnd = savedContainerEnd;
+                    declarationListContainerEnd = savedDeclarationListContainerEnd;
+                    // Emit trailing comments if the position is not synthesized and the node
+                    // has not opted out from emitting leading comments and is an emitted node.
+                    if (!skipTrailingComments && isEmittedNode) {
+                        emitTrailingComments(end);
+                    }
+                    if (extendedDiagnostics) {
+                        ts.performance.measure("commentTime", "postEmitNodeWithComment");
+                    }
+                }
+            }
+        }
+        function emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback) {
+            var leadingComments = emitNode && emitNode.leadingComments;
+            if (ts.some(leadingComments)) {
+                if (extendedDiagnostics) {
+                    ts.performance.mark("preEmitNodeWithSynthesizedComments");
+                }
+                ts.forEach(leadingComments, emitLeadingSynthesizedComment);
+                if (extendedDiagnostics) {
+                    ts.performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
+                }
+            }
+            emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
+            var trailingComments = emitNode && emitNode.trailingComments;
+            if (ts.some(trailingComments)) {
+                if (extendedDiagnostics) {
+                    ts.performance.mark("postEmitNodeWithSynthesizedComments");
+                }
+                ts.forEach(trailingComments, emitTrailingSynthesizedComment);
+                if (extendedDiagnostics) {
+                    ts.performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
+                }
+            }
+        }
+        function emitLeadingSynthesizedComment(comment) {
+            if (comment.kind === 2 /* SingleLineCommentTrivia */) {
+                writer.writeLine();
+            }
+            writeSynthesizedComment(comment);
+            if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
+                writer.writeLine();
+            }
+            else {
+                writer.write(" ");
+            }
+        }
+        function emitTrailingSynthesizedComment(comment) {
+            if (!writer.isAtStartOfLine()) {
+                writer.write(" ");
+            }
+            writeSynthesizedComment(comment);
+            if (comment.hasTrailingNewLine) {
+                writer.writeLine();
+            }
+        }
+        function writeSynthesizedComment(comment) {
+            var text = formatSynthesizedComment(comment);
+            var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined;
+            ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
+        }
+        function formatSynthesizedComment(comment) {
+            return comment.kind === 3 /* MultiLineCommentTrivia */
+                ? "/*" + comment.text + "*/"
+                : "//" + comment.text;
+        }
+        function emitNodeWithNestedComments(hint, node, emitFlags, emitCallback) {
+            if (emitFlags & 2048 /* NoNestedComments */) {
+                disabled = true;
+                emitCallback(hint, node);
+                disabled = false;
+            }
+            else {
+                emitCallback(hint, node);
+            }
+        }
+        function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
+            if (extendedDiagnostics) {
+                ts.performance.mark("preEmitBodyWithDetachedComments");
+            }
+            var pos = detachedRange.pos, end = detachedRange.end;
+            var emitFlags = ts.getEmitFlags(node);
+            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0;
+            var skipTrailingComments = disabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0;
+            if (!skipLeadingComments) {
+                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
+            }
+            if (extendedDiagnostics) {
+                ts.performance.measure("commentTime", "preEmitBodyWithDetachedComments");
+            }
+            if (emitFlags & 2048 /* NoNestedComments */ && !disabled) {
+                disabled = true;
+                emitCallback(node);
+                disabled = false;
+            }
+            else {
+                emitCallback(node);
+            }
+            if (extendedDiagnostics) {
+                ts.performance.mark("beginEmitBodyWithDetachedCommetns");
+            }
+            if (!skipTrailingComments) {
+                emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
+                if (hasWrittenComment && !writer.isAtStartOfLine()) {
+                    writer.writeLine();
+                }
+            }
+            if (extendedDiagnostics) {
+                ts.performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns");
+            }
+        }
+        function emitLeadingComments(pos, isEmittedNode) {
+            hasWrittenComment = false;
+            if (isEmittedNode) {
+                forEachLeadingCommentToEmit(pos, emitLeadingComment);
+            }
+            else if (pos === 0) {
+                // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
+                // unless it is a triple slash comment at the top of the file.
+                // For Example:
+                //      /// <reference-path ...>
+                //      declare var x;
+                //      /// <reference-path ...>
+                //      interface F {}
+                //  The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
+                forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
+            }
+        }
+        function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
+            if (isTripleSlashComment(commentPos, commentEnd)) {
+                emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
+            }
+        }
+        function emitLeadingComment(commentPos, commentEnd, _kind, hasTrailingNewLine, rangePos) {
+            if (!hasWrittenComment) {
+                ts.emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
+                hasWrittenComment = true;
+            }
+            // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
+            if (emitPos)
+                emitPos(commentPos);
+            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
+            if (emitPos)
+                emitPos(commentEnd);
+            if (hasTrailingNewLine) {
+                writer.writeLine();
+            }
+            else {
+                writer.write(" ");
+            }
+        }
+        function emitLeadingCommentsOfPosition(pos) {
+            if (disabled || pos === -1) {
+                return;
+            }
+            emitLeadingComments(pos, /*isEmittedNode*/ true);
+        }
+        function emitTrailingComments(pos) {
+            forEachTrailingCommentToEmit(pos, emitTrailingComment);
+        }
+        function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
+            // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
+            if (!writer.isAtStartOfLine()) {
+                writer.write(" ");
+            }
+            if (emitPos)
+                emitPos(commentPos);
+            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
+            if (emitPos)
+                emitPos(commentEnd);
+            if (hasTrailingNewLine) {
+                writer.writeLine();
+            }
+        }
+        function emitTrailingCommentsOfPosition(pos, prefixSpace) {
+            if (disabled) {
+                return;
+            }
+            if (extendedDiagnostics) {
+                ts.performance.mark("beforeEmitTrailingCommentsOfPosition");
+            }
+            forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
+            if (extendedDiagnostics) {
+                ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition");
+            }
+        }
+        function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
+            // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
+            if (emitPos)
+                emitPos(commentPos);
+            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
+            if (emitPos)
+                emitPos(commentEnd);
+            if (hasTrailingNewLine) {
+                writer.writeLine();
+            }
+            else {
+                writer.write(" ");
+            }
+        }
+        function forEachLeadingCommentToEmit(pos, cb) {
+            // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
+            if (containerPos === -1 || pos !== containerPos) {
+                if (hasDetachedComments(pos)) {
+                    forEachLeadingCommentWithoutDetachedComments(cb);
+                }
+                else {
+                    ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
+                }
+            }
+        }
+        function forEachTrailingCommentToEmit(end, cb) {
+            // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
+            if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) {
+                ts.forEachTrailingCommentRange(currentText, end, cb);
+            }
+        }
+        function reset() {
+            currentSourceFile = undefined;
+            currentText = undefined;
+            currentLineMap = undefined;
+            detachedCommentsInfo = undefined;
+        }
+        function setWriter(output) {
+            writer = output;
+        }
+        function setSourceFile(sourceFile) {
+            currentSourceFile = sourceFile;
+            currentText = currentSourceFile.text;
+            currentLineMap = ts.getLineStarts(currentSourceFile);
+            detachedCommentsInfo = undefined;
+        }
+        function hasDetachedComments(pos) {
+            return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos;
+        }
+        function forEachLeadingCommentWithoutDetachedComments(cb) {
+            // get the leading comments from detachedPos
+            var pos = ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos;
+            if (detachedCommentsInfo.length - 1) {
+                detachedCommentsInfo.pop();
+            }
+            else {
+                detachedCommentsInfo = undefined;
+            }
+            ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
+        }
+        function emitDetachedCommentsAndUpdateCommentsInfo(range) {
+            var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, range, newLine, disabled);
+            if (currentDetachedCommentInfo) {
+                if (detachedCommentsInfo) {
+                    detachedCommentsInfo.push(currentDetachedCommentInfo);
+                }
+                else {
+                    detachedCommentsInfo = [currentDetachedCommentInfo];
+                }
+            }
+        }
+        function writeComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
+            if (emitPos)
+                emitPos(commentPos);
+            ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
+            if (emitPos)
+                emitPos(commentEnd);
+        }
+        /**
+         * Determine if the given comment is a triple-slash
+         *
+         * @return true if the comment is a triple-slash comment else false
+         */
+        function isTripleSlashComment(commentPos, commentEnd) {
+            return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd);
+        }
+    }
+    ts.createCommentWriter = createCommentWriter;
+})(ts || (ts = {}));
+/// <reference path="checker.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    function getDeclarationDiagnostics(host, resolver, targetSourceFile) {
+        var declarationDiagnostics = ts.createDiagnosticCollection();
+        ts.forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
+        return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
+        function getDeclarationDiagnosticsFromFile(_a, sourceFileOrBundle) {
+            var declarationFilePath = _a.declarationFilePath;
+            emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
+        }
+    }
+    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
+    function emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles) {
+        var sourceFiles = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
+        var isBundledEmit = sourceFileOrBundle.kind === 266 /* Bundle */;
+        var newLine = host.getNewLine();
+        var compilerOptions = host.getCompilerOptions();
+        var write;
+        var writeLine;
+        var increaseIndent;
+        var decreaseIndent;
+        var writeTextOfNode;
+        var writer;
+        createAndSetNewTextWriterWithSymbolWriter();
+        var enclosingDeclaration;
+        var resultHasExternalModuleIndicator;
+        var currentText;
+        var currentLineMap;
+        var currentIdentifiers;
+        var isCurrentFileExternalModule;
+        var reportedDeclarationError = false;
+        var errorNameNode;
+        var emitJsDocComments = compilerOptions.removeComments ? ts.noop : writeJsDocComments;
+        var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
+        var needsDeclare = true;
+        var moduleElementDeclarationEmitInfo = [];
+        var asynchronousSubModuleDeclarationEmitInfo;
+        // Contains the reference paths that needs to go in the declaration file.
+        // Collecting this separately because reference paths need to be first thing in the declaration file
+        // and we could be collecting these paths from multiple files into single one with --out option
+        var referencesOutput = "";
+        var usedTypeDirectiveReferences;
+        // Emit references corresponding to each file
+        var emittedReferencedFiles = [];
+        var addedGlobalFileReference = false;
+        var allSourcesModuleElementDeclarationEmitInfo = [];
+        ts.forEach(sourceFiles, function (sourceFile) {
+            // Dont emit for javascript file
+            if (ts.isSourceFileJavaScript(sourceFile)) {
+                return;
+            }
+            // Check what references need to be added
+            if (!compilerOptions.noResolve) {
+                ts.forEach(sourceFile.referencedFiles, function (fileReference) {
+                    var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
+                    // Emit reference in dts, if the file reference was not already emitted
+                    if (referencedFile && !ts.contains(emittedReferencedFiles, referencedFile)) {
+                        // Add a reference to generated dts file,
+                        // global file reference is added only
+                        //  - if it is not bundled emit (because otherwise it would be self reference)
+                        //  - and it is not already added
+                        if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference, emitOnlyDtsFiles)) {
+                            addedGlobalFileReference = true;
+                        }
+                        emittedReferencedFiles.push(referencedFile);
+                    }
+                });
+            }
+            resultHasExternalModuleIndicator = false;
+            if (!isBundledEmit || !ts.isExternalModule(sourceFile)) {
+                needsDeclare = true;
+                emitSourceFile(sourceFile);
+            }
+            else if (ts.isExternalModule(sourceFile)) {
+                needsDeclare = false;
+                write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
+                writeLine();
+                increaseIndent();
+                emitSourceFile(sourceFile);
+                decreaseIndent();
+                write("}");
+                writeLine();
+            }
+            // create asynchronous output for the importDeclarations
+            if (moduleElementDeclarationEmitInfo.length) {
+                var oldWriter = writer;
+                ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+                    if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
+                        ts.Debug.assert(aliasEmitInfo.node.kind === 238 /* ImportDeclaration */);
+                        createAndSetNewTextWriterWithSymbolWriter();
+                        ts.Debug.assert(aliasEmitInfo.indent === 0 || (aliasEmitInfo.indent === 1 && isBundledEmit));
+                        for (var i = 0; i < aliasEmitInfo.indent; i++) {
+                            increaseIndent();
+                        }
+                        writeImportDeclaration(aliasEmitInfo.node);
+                        aliasEmitInfo.asynchronousOutput = writer.getText();
+                        for (var i = 0; i < aliasEmitInfo.indent; i++) {
+                            decreaseIndent();
+                        }
+                    }
+                });
+                setWriter(oldWriter);
+                allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+                moduleElementDeclarationEmitInfo = [];
+            }
+            if (!isBundledEmit && ts.isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
+                // if file was external module with augmentations - this fact should be preserved in .d.ts as well.
+                // in case if we didn't write any external module specifiers in .d.ts we need to emit something
+                // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
+                write("export {};");
+                writeLine();
+            }
+        });
+        if (usedTypeDirectiveReferences) {
+            ts.forEachKey(usedTypeDirectiveReferences, function (directive) {
+                referencesOutput += "/// <reference types=\"" + directive + "\" />" + newLine;
+            });
+        }
+        return {
+            reportedDeclarationError: reportedDeclarationError,
+            moduleElementDeclarationEmitInfo: allSourcesModuleElementDeclarationEmitInfo,
+            synchronousDeclarationOutput: writer.getText(),
+            referencesOutput: referencesOutput,
+        };
+        function hasInternalAnnotation(range) {
+            var comment = currentText.substring(range.pos, range.end);
+            return ts.stringContains(comment, "@internal");
+        }
+        function stripInternal(node) {
+            if (node) {
+                var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
+                if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
+                    return;
+                }
+                emitNode(node);
+            }
+        }
+        function createAndSetNewTextWriterWithSymbolWriter() {
+            var writer = ts.createTextWriter(newLine);
+            writer.trackSymbol = trackSymbol;
+            writer.reportInaccessibleThisError = reportInaccessibleThisError;
+            writer.reportPrivateInBaseOfClassExpression = reportPrivateInBaseOfClassExpression;
+            writer.writeKeyword = writer.write;
+            writer.writeOperator = writer.write;
+            writer.writePunctuation = writer.write;
+            writer.writeSpace = writer.write;
+            writer.writeStringLiteral = writer.writeLiteral;
+            writer.writeParameter = writer.write;
+            writer.writeProperty = writer.write;
+            writer.writeSymbol = writer.write;
+            setWriter(writer);
+        }
+        function setWriter(newWriter) {
+            writer = newWriter;
+            write = newWriter.write;
+            writeTextOfNode = newWriter.writeTextOfNode;
+            writeLine = newWriter.writeLine;
+            increaseIndent = newWriter.increaseIndent;
+            decreaseIndent = newWriter.decreaseIndent;
+        }
+        function writeAsynchronousModuleElements(nodes) {
+            var oldWriter = writer;
+            ts.forEach(nodes, function (declaration) {
+                var nodeToCheck;
+                if (declaration.kind === 226 /* VariableDeclaration */) {
+                    nodeToCheck = declaration.parent.parent;
+                }
+                else if (declaration.kind === 241 /* NamedImports */ || declaration.kind === 242 /* ImportSpecifier */ || declaration.kind === 239 /* ImportClause */) {
+                    ts.Debug.fail("We should be getting ImportDeclaration instead to write");
+                }
+                else {
+                    nodeToCheck = declaration;
+                }
+                var moduleElementEmitInfo = ts.forEach(moduleElementDeclarationEmitInfo, function (declEmitInfo) { return declEmitInfo.node === nodeToCheck ? declEmitInfo : undefined; });
+                if (!moduleElementEmitInfo && asynchronousSubModuleDeclarationEmitInfo) {
+                    moduleElementEmitInfo = ts.forEach(asynchronousSubModuleDeclarationEmitInfo, function (declEmitInfo) { return declEmitInfo.node === nodeToCheck ? declEmitInfo : undefined; });
+                }
+                // If the alias was marked as not visible when we saw its declaration, we would have saved the aliasEmitInfo, but if we haven't yet visited the alias declaration
+                // then we don't need to write it at this point. We will write it when we actually see its declaration
+                // Eg.
+                // export function bar(a: foo.Foo) { }
+                // import foo = require("foo");
+                // Writing of function bar would mark alias declaration foo as visible but we haven't yet visited that declaration so do nothing,
+                // we would write alias foo declaration when we visit it since it would now be marked as visible
+                if (moduleElementEmitInfo) {
+                    if (moduleElementEmitInfo.node.kind === 238 /* ImportDeclaration */) {
+                        // we have to create asynchronous output only after we have collected complete information
+                        // because it is possible to enable multiple bindings as asynchronously visible
+                        moduleElementEmitInfo.isVisible = true;
+                    }
+                    else {
+                        createAndSetNewTextWriterWithSymbolWriter();
+                        for (var declarationIndent = moduleElementEmitInfo.indent; declarationIndent; declarationIndent--) {
+                            increaseIndent();
+                        }
+                        if (nodeToCheck.kind === 233 /* ModuleDeclaration */) {
+                            ts.Debug.assert(asynchronousSubModuleDeclarationEmitInfo === undefined);
+                            asynchronousSubModuleDeclarationEmitInfo = [];
+                        }
+                        writeModuleElement(nodeToCheck);
+                        if (nodeToCheck.kind === 233 /* ModuleDeclaration */) {
+                            moduleElementEmitInfo.subModuleElementDeclarationEmitInfo = asynchronousSubModuleDeclarationEmitInfo;
+                            asynchronousSubModuleDeclarationEmitInfo = undefined;
+                        }
+                        moduleElementEmitInfo.asynchronousOutput = writer.getText();
+                    }
+                }
+            });
+            setWriter(oldWriter);
+        }
+        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
+            if (!typeReferenceDirectives) {
+                return;
+            }
+            if (!usedTypeDirectiveReferences) {
+                usedTypeDirectiveReferences = ts.createMap();
+            }
+            for (var _i = 0, typeReferenceDirectives_1 = typeReferenceDirectives; _i < typeReferenceDirectives_1.length; _i++) {
+                var directive = typeReferenceDirectives_1[_i];
+                if (!usedTypeDirectiveReferences.has(directive)) {
+                    usedTypeDirectiveReferences.set(directive, directive);
+                }
+            }
+        }
+        function handleSymbolAccessibilityError(symbolAccessibilityResult) {
+            if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
+                // write the aliases
+                if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
+                    writeAsynchronousModuleElements(symbolAccessibilityResult.aliasesToMakeVisible);
+                }
+            }
+            else {
+                // Report error
+                reportedDeclarationError = true;
+                var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
+                if (errorInfo) {
+                    if (errorInfo.typeName) {
+                        emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
+                    }
+                    else {
+                        emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
+                    }
+                }
+            }
+        }
+        function trackSymbol(symbol, enclosingDeclaration, meaning) {
+            handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
+            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
+        }
+        function reportPrivateInBaseOfClassExpression(propertyName) {
+            if (errorNameNode) {
+                reportedDeclarationError = true;
+                emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
+            }
+        }
+        function reportInaccessibleThisError() {
+            if (errorNameNode) {
+                reportedDeclarationError = true;
+                emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode)));
+            }
+        }
+        function writeTypeOfDeclaration(declaration, type, getSymbolAccessibilityDiagnostic) {
+            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
+            write(": ");
+            // use the checker's type, not the declared type,
+            // for optional parameter properties
+            // and also for non-optional initialized parameters that aren't a parameter property
+            // these types may need to add `undefined`.
+            var shouldUseResolverType = declaration.kind === 146 /* Parameter */ &&
+                (resolver.isRequiredInitializedParameter(declaration) ||
+                    resolver.isOptionalUninitializedParameterProperty(declaration));
+            if (type && !shouldUseResolverType) {
+                // Write the type
+                emitType(type);
+            }
+            else {
+                errorNameNode = declaration.name;
+                var format = 4 /* UseTypeOfFunction */ |
+                    16384 /* WriteClassExpressionAsTypeLiteral */ |
+                    (shouldUseResolverType ? 8192 /* AddUndefined */ : 0);
+                resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
+                errorNameNode = undefined;
+            }
+        }
+        function writeReturnTypeAtSignature(signature, getSymbolAccessibilityDiagnostic) {
+            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
+            write(": ");
+            if (signature.type) {
+                // Write the type
+                emitType(signature.type);
+            }
+            else {
+                errorNameNode = signature.name;
+                resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer);
+                errorNameNode = undefined;
+            }
+        }
+        function emitLines(nodes) {
+            for (var _i = 0, nodes_6 = nodes; _i < nodes_6.length; _i++) {
+                var node = nodes_6[_i];
+                emit(node);
+            }
+        }
+        function emitSeparatedList(nodes, separator, eachNodeEmitFn, canEmitFn) {
+            var currentWriterPos = writer.getTextPos();
+            for (var _i = 0, nodes_7 = nodes; _i < nodes_7.length; _i++) {
+                var node = nodes_7[_i];
+                if (!canEmitFn || canEmitFn(node)) {
+                    if (currentWriterPos !== writer.getTextPos()) {
+                        write(separator);
+                    }
+                    currentWriterPos = writer.getTextPos();
+                    eachNodeEmitFn(node);
+                }
+            }
+        }
+        function emitCommaList(nodes, eachNodeEmitFn, canEmitFn) {
+            emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
+        }
+        function writeJsDocComments(declaration) {
+            if (declaration) {
+                var jsDocComments = ts.getJSDocCommentRanges(declaration, currentText);
+                ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
+                // jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
+                ts.emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
+            }
+        }
+        function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
+            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
+            emitType(type);
+        }
+        function emitType(type) {
+            switch (type.kind) {
+                case 119 /* AnyKeyword */:
+                case 136 /* StringKeyword */:
+                case 133 /* NumberKeyword */:
+                case 122 /* BooleanKeyword */:
+                case 134 /* ObjectKeyword */:
+                case 137 /* SymbolKeyword */:
+                case 105 /* VoidKeyword */:
+                case 139 /* UndefinedKeyword */:
+                case 95 /* NullKeyword */:
+                case 130 /* NeverKeyword */:
+                case 169 /* ThisType */:
+                case 173 /* LiteralType */:
+                    return writeTextOfNode(currentText, type);
+                case 201 /* ExpressionWithTypeArguments */:
+                    return emitExpressionWithTypeArguments(type);
+                case 159 /* TypeReference */:
+                    return emitTypeReference(type);
+                case 162 /* TypeQuery */:
+                    return emitTypeQuery(type);
+                case 164 /* ArrayType */:
+                    return emitArrayType(type);
+                case 165 /* TupleType */:
+                    return emitTupleType(type);
+                case 166 /* UnionType */:
+                    return emitUnionType(type);
+                case 167 /* IntersectionType */:
+                    return emitIntersectionType(type);
+                case 168 /* ParenthesizedType */:
+                    return emitParenType(type);
+                case 170 /* TypeOperator */:
+                    return emitTypeOperator(type);
+                case 171 /* IndexedAccessType */:
+                    return emitIndexedAccessType(type);
+                case 172 /* MappedType */:
+                    return emitMappedType(type);
+                case 160 /* FunctionType */:
+                case 161 /* ConstructorType */:
+                    return emitSignatureDeclarationWithJsDocComments(type);
+                case 163 /* TypeLiteral */:
+                    return emitTypeLiteral(type);
+                case 71 /* Identifier */:
+                    return emitEntityName(type);
+                case 143 /* QualifiedName */:
+                    return emitEntityName(type);
+                case 158 /* TypePredicate */:
+                    return emitTypePredicate(type);
+            }
+            function writeEntityName(entityName) {
+                if (entityName.kind === 71 /* Identifier */) {
+                    writeTextOfNode(currentText, entityName);
+                }
+                else {
+                    var left = entityName.kind === 143 /* QualifiedName */ ? entityName.left : entityName.expression;
+                    var right = entityName.kind === 143 /* QualifiedName */ ? entityName.right : entityName.name;
+                    writeEntityName(left);
+                    write(".");
+                    writeTextOfNode(currentText, right);
+                }
+            }
+            function emitEntityName(entityName) {
+                var visibilityResult = resolver.isEntityNameVisible(entityName, 
+                // Aliases can be written asynchronously so use correct enclosing declaration
+                entityName.parent.kind === 237 /* ImportEqualsDeclaration */ ? entityName.parent : enclosingDeclaration);
+                handleSymbolAccessibilityError(visibilityResult);
+                recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
+                writeEntityName(entityName);
+            }
+            function emitExpressionWithTypeArguments(node) {
+                if (ts.isEntityNameExpression(node.expression)) {
+                    ts.Debug.assert(node.expression.kind === 71 /* Identifier */ || node.expression.kind === 179 /* PropertyAccessExpression */);
+                    emitEntityName(node.expression);
+                    if (node.typeArguments) {
+                        write("<");
+                        emitCommaList(node.typeArguments, emitType);
+                        write(">");
+                    }
+                }
+            }
+            function emitTypeReference(type) {
+                emitEntityName(type.typeName);
+                if (type.typeArguments) {
+                    write("<");
+                    emitCommaList(type.typeArguments, emitType);
+                    write(">");
+                }
+            }
+            function emitTypePredicate(type) {
+                writeTextOfNode(currentText, type.parameterName);
+                write(" is ");
+                emitType(type.type);
+            }
+            function emitTypeQuery(type) {
+                write("typeof ");
+                emitEntityName(type.exprName);
+            }
+            function emitArrayType(type) {
+                emitType(type.elementType);
+                write("[]");
+            }
+            function emitTupleType(type) {
+                write("[");
+                emitCommaList(type.elementTypes, emitType);
+                write("]");
+            }
+            function emitUnionType(type) {
+                emitSeparatedList(type.types, " | ", emitType);
+            }
+            function emitIntersectionType(type) {
+                emitSeparatedList(type.types, " & ", emitType);
+            }
+            function emitParenType(type) {
+                write("(");
+                emitType(type.type);
+                write(")");
+            }
+            function emitTypeOperator(type) {
+                write(ts.tokenToString(type.operator));
+                write(" ");
+                emitType(type.type);
+            }
+            function emitIndexedAccessType(node) {
+                emitType(node.objectType);
+                write("[");
+                emitType(node.indexType);
+                write("]");
+            }
+            function emitMappedType(node) {
+                var prevEnclosingDeclaration = enclosingDeclaration;
+                enclosingDeclaration = node;
+                write("{");
+                writeLine();
+                increaseIndent();
+                if (node.readonlyToken) {
+                    write("readonly ");
+                }
+                write("[");
+                writeEntityName(node.typeParameter.name);
+                write(" in ");
+                emitType(node.typeParameter.constraint);
+                write("]");
+                if (node.questionToken) {
+                    write("?");
+                }
+                write(": ");
+                emitType(node.type);
+                write(";");
+                writeLine();
+                decreaseIndent();
+                write("}");
+                enclosingDeclaration = prevEnclosingDeclaration;
+            }
+            function emitTypeLiteral(type) {
+                write("{");
+                if (type.members.length) {
+                    writeLine();
+                    increaseIndent();
+                    // write members
+                    emitLines(type.members);
+                    decreaseIndent();
+                }
+                write("}");
+            }
+        }
+        function emitSourceFile(node) {
+            currentText = node.text;
+            currentLineMap = ts.getLineStarts(node);
+            currentIdentifiers = node.identifiers;
+            isCurrentFileExternalModule = ts.isExternalModule(node);
+            enclosingDeclaration = node;
+            ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, /*removeComments*/ true);
+            emitLines(node.statements);
+        }
+        // Return a temp variable name to be used in `export default`/`export class ... extends` statements.
+        // The temp name will be of the form _default_counter.
+        // Note that export default is only allowed at most once in a module, so we
+        // do not need to keep track of created temp names.
+        function getExportTempVariableName(baseName) {
+            if (!currentIdentifiers.has(baseName)) {
+                return baseName;
+            }
+            var count = 0;
+            while (true) {
+                count++;
+                var name = baseName + "_" + count;
+                if (!currentIdentifiers.has(name)) {
+                    return name;
+                }
+            }
+        }
+        function emitTempVariableDeclaration(expr, baseName, diagnostic, needsDeclare) {
+            var tempVarName = getExportTempVariableName(baseName);
+            if (needsDeclare) {
+                write("declare ");
+            }
+            write("const ");
+            write(tempVarName);
+            write(": ");
+            writer.getSymbolAccessibilityDiagnostic = function () { return diagnostic; };
+            resolver.writeTypeOfExpression(expr, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer);
+            write(";");
+            writeLine();
+            return tempVarName;
+        }
+        function emitExportAssignment(node) {
+            if (node.expression.kind === 71 /* Identifier */) {
+                write(node.isExportEquals ? "export = " : "export default ");
+                writeTextOfNode(currentText, node.expression);
+            }
+            else {
+                var tempVarName = emitTempVariableDeclaration(node.expression, "_default", {
+                    diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
+                    errorNode: node
+                }, needsDeclare);
+                write(node.isExportEquals ? "export = " : "export default ");
+                write(tempVarName);
+            }
+            write(";");
+            writeLine();
+            // Make all the declarations visible for the export name
+            if (node.expression.kind === 71 /* Identifier */) {
+                var nodes = resolver.collectLinkedAliases(node.expression);
+                // write each of these declarations asynchronously
+                writeAsynchronousModuleElements(nodes);
+            }
+        }
+        function isModuleElementVisible(node) {
+            return resolver.isDeclarationVisible(node);
+        }
+        function emitModuleElement(node, isModuleElementVisible) {
+            if (isModuleElementVisible) {
+                writeModuleElement(node);
+            }
+            else if (node.kind === 237 /* ImportEqualsDeclaration */ ||
+                (node.parent.kind === 265 /* SourceFile */ && isCurrentFileExternalModule)) {
+                var isVisible = void 0;
+                if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 265 /* SourceFile */) {
+                    // Import declaration of another module that is visited async so lets put it in right spot
+                    asynchronousSubModuleDeclarationEmitInfo.push({
+                        node: node,
+                        outputPos: writer.getTextPos(),
+                        indent: writer.getIndent(),
+                        isVisible: isVisible
+                    });
+                }
+                else {
+                    if (node.kind === 238 /* ImportDeclaration */) {
+                        var importDeclaration = node;
+                        if (importDeclaration.importClause) {
+                            isVisible = (importDeclaration.importClause.name && resolver.isDeclarationVisible(importDeclaration.importClause)) ||
+                                isVisibleNamedBinding(importDeclaration.importClause.namedBindings);
+                        }
+                    }
+                    moduleElementDeclarationEmitInfo.push({
+                        node: node,
+                        outputPos: writer.getTextPos(),
+                        indent: writer.getIndent(),
+                        isVisible: isVisible
+                    });
+                }
+            }
+        }
+        function writeModuleElement(node) {
+            switch (node.kind) {
+                case 228 /* FunctionDeclaration */:
+                    return writeFunctionDeclaration(node);
+                case 208 /* VariableStatement */:
+                    return writeVariableStatement(node);
+                case 230 /* InterfaceDeclaration */:
+                    return writeInterfaceDeclaration(node);
+                case 229 /* ClassDeclaration */:
+                    return writeClassDeclaration(node);
+                case 231 /* TypeAliasDeclaration */:
+                    return writeTypeAliasDeclaration(node);
+                case 232 /* EnumDeclaration */:
+                    return writeEnumDeclaration(node);
+                case 233 /* ModuleDeclaration */:
+                    return writeModuleDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return writeImportEqualsDeclaration(node);
+                case 238 /* ImportDeclaration */:
+                    return writeImportDeclaration(node);
+                default:
+                    ts.Debug.fail("Unknown symbol kind");
+            }
+        }
+        function emitModuleElementDeclarationFlags(node) {
+            // If the node is parented in the current source file we need to emit export declare or just export
+            if (node.parent.kind === 265 /* SourceFile */) {
+                var modifiers = ts.getModifierFlags(node);
+                // If the node is exported
+                if (modifiers & 1 /* Export */) {
+                    write("export ");
+                }
+                if (modifiers & 512 /* Default */) {
+                    write("default ");
+                }
+                else if (node.kind !== 230 /* InterfaceDeclaration */ && needsDeclare) {
+                    write("declare ");
+                }
+            }
+        }
+        function emitClassMemberDeclarationFlags(flags) {
+            if (flags & 8 /* Private */) {
+                write("private ");
+            }
+            else if (flags & 16 /* Protected */) {
+                write("protected ");
+            }
+            if (flags & 32 /* Static */) {
+                write("static ");
+            }
+            if (flags & 64 /* Readonly */) {
+                write("readonly ");
+            }
+            if (flags & 128 /* Abstract */) {
+                write("abstract ");
+            }
+        }
+        function writeImportEqualsDeclaration(node) {
+            // note usage of writer. methods instead of aliases created, just to make sure we are using
+            // correct writer especially to handle asynchronous alias writing
+            emitJsDocComments(node);
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                write("export ");
+            }
+            write("import ");
+            writeTextOfNode(currentText, node.name);
+            write(" = ");
+            if (ts.isInternalModuleImportEqualsDeclaration(node)) {
+                emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
+                write(";");
+            }
+            else {
+                write("require(");
+                emitExternalModuleSpecifier(node);
+                write(");");
+            }
+            writer.writeLine();
+            function getImportEntityNameVisibilityError() {
+                return {
+                    diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
+                    errorNode: node,
+                    typeName: node.name
+                };
+            }
+        }
+        function isVisibleNamedBinding(namedBindings) {
+            if (namedBindings) {
+                if (namedBindings.kind === 240 /* NamespaceImport */) {
+                    return resolver.isDeclarationVisible(namedBindings);
+                }
+                else {
+                    return ts.forEach(namedBindings.elements, function (namedImport) { return resolver.isDeclarationVisible(namedImport); });
+                }
+            }
+        }
+        function writeImportDeclaration(node) {
+            emitJsDocComments(node);
+            if (ts.hasModifier(node, 1 /* Export */)) {
+                write("export ");
+            }
+            write("import ");
+            if (node.importClause) {
+                var currentWriterPos = writer.getTextPos();
+                if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
+                    writeTextOfNode(currentText, node.importClause.name);
+                }
+                if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
+                    if (currentWriterPos !== writer.getTextPos()) {
+                        // If the default binding was emitted, write the separated
+                        write(", ");
+                    }
+                    if (node.importClause.namedBindings.kind === 240 /* NamespaceImport */) {
+                        write("* as ");
+                        writeTextOfNode(currentText, node.importClause.namedBindings.name);
+                    }
+                    else {
+                        write("{ ");
+                        emitCommaList(node.importClause.namedBindings.elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible);
+                        write(" }");
+                    }
+                }
+                write(" from ");
+            }
+            emitExternalModuleSpecifier(node);
+            write(";");
+            writer.writeLine();
+        }
+        function emitExternalModuleSpecifier(parent) {
+            // emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
+            // the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
+            // external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
+            // so compiler will treat them as external modules.
+            resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== 233 /* ModuleDeclaration */;
+            var moduleSpecifier;
+            if (parent.kind === 237 /* ImportEqualsDeclaration */) {
+                var node = parent;
+                moduleSpecifier = ts.getExternalModuleImportEqualsDeclarationExpression(node);
+            }
+            else if (parent.kind === 233 /* ModuleDeclaration */) {
+                moduleSpecifier = parent.name;
+            }
+            else {
+                var node = parent;
+                moduleSpecifier = node.moduleSpecifier;
+            }
+            if (moduleSpecifier.kind === 9 /* StringLiteral */ && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
+                var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, parent);
+                if (moduleName) {
+                    write('"');
+                    write(moduleName);
+                    write('"');
+                    return;
+                }
+            }
+            writeTextOfNode(currentText, moduleSpecifier);
+        }
+        function emitImportOrExportSpecifier(node) {
+            if (node.propertyName) {
+                writeTextOfNode(currentText, node.propertyName);
+                write(" as ");
+            }
+            writeTextOfNode(currentText, node.name);
+        }
+        function emitExportSpecifier(node) {
+            emitImportOrExportSpecifier(node);
+            // Make all the declarations visible for the export name
+            var nodes = resolver.collectLinkedAliases(node.propertyName || node.name);
+            // write each of these declarations asynchronously
+            writeAsynchronousModuleElements(nodes);
+        }
+        function emitExportDeclaration(node) {
+            emitJsDocComments(node);
+            write("export ");
+            if (node.exportClause) {
+                write("{ ");
+                emitCommaList(node.exportClause.elements, emitExportSpecifier);
+                write(" }");
+            }
+            else {
+                write("*");
+            }
+            if (node.moduleSpecifier) {
+                write(" from ");
+                emitExternalModuleSpecifier(node);
+            }
+            write(";");
+            writer.writeLine();
+        }
+        function writeModuleDeclaration(node) {
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            if (ts.isGlobalScopeAugmentation(node)) {
+                write("global ");
+            }
+            else {
+                if (node.flags & 16 /* Namespace */) {
+                    write("namespace ");
+                }
+                else {
+                    write("module ");
+                }
+                if (ts.isExternalModuleAugmentation(node)) {
+                    emitExternalModuleSpecifier(node);
+                }
+                else {
+                    writeTextOfNode(currentText, node.name);
+                }
+            }
+            while (node.body && node.body.kind !== 234 /* ModuleBlock */) {
+                node = node.body;
+                write(".");
+                writeTextOfNode(currentText, node.name);
+            }
+            var prevEnclosingDeclaration = enclosingDeclaration;
+            if (node.body) {
+                enclosingDeclaration = node;
+                write(" {");
+                writeLine();
+                increaseIndent();
+                emitLines(node.body.statements);
+                decreaseIndent();
+                write("}");
+                writeLine();
+                enclosingDeclaration = prevEnclosingDeclaration;
+            }
+            else {
+                write(";");
+            }
+        }
+        function writeTypeAliasDeclaration(node) {
+            var prevEnclosingDeclaration = enclosingDeclaration;
+            enclosingDeclaration = node;
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            write("type ");
+            writeTextOfNode(currentText, node.name);
+            emitTypeParameters(node.typeParameters);
+            write(" = ");
+            emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
+            write(";");
+            writeLine();
+            enclosingDeclaration = prevEnclosingDeclaration;
+            function getTypeAliasDeclarationVisibilityError() {
+                return {
+                    diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
+                    errorNode: node.type,
+                    typeName: node.name
+                };
+            }
+        }
+        function writeEnumDeclaration(node) {
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            if (ts.isConst(node)) {
+                write("const ");
+            }
+            write("enum ");
+            writeTextOfNode(currentText, node.name);
+            write(" {");
+            writeLine();
+            increaseIndent();
+            emitLines(node.members);
+            decreaseIndent();
+            write("}");
+            writeLine();
+        }
+        function emitEnumMemberDeclaration(node) {
+            emitJsDocComments(node);
+            writeTextOfNode(currentText, node.name);
+            var enumMemberValue = resolver.getConstantValue(node);
+            if (enumMemberValue !== undefined) {
+                write(" = ");
+                write(ts.getTextOfConstantValue(enumMemberValue));
+            }
+            write(",");
+            writeLine();
+        }
+        function isPrivateMethodTypeParameter(node) {
+            return node.parent.kind === 151 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */);
+        }
+        function emitTypeParameters(typeParameters) {
+            function emitTypeParameter(node) {
+                increaseIndent();
+                emitJsDocComments(node);
+                decreaseIndent();
+                writeTextOfNode(currentText, node.name);
+                // If there is constraint present and this is not a type parameter of the private method emit the constraint
+                if (node.constraint && !isPrivateMethodTypeParameter(node)) {
+                    write(" extends ");
+                    if (node.parent.kind === 160 /* FunctionType */ ||
+                        node.parent.kind === 161 /* ConstructorType */ ||
+                        (node.parent.parent && node.parent.parent.kind === 163 /* TypeLiteral */)) {
+                        ts.Debug.assert(node.parent.kind === 151 /* MethodDeclaration */ ||
+                            node.parent.kind === 150 /* MethodSignature */ ||
+                            node.parent.kind === 160 /* FunctionType */ ||
+                            node.parent.kind === 161 /* ConstructorType */ ||
+                            node.parent.kind === 155 /* CallSignature */ ||
+                            node.parent.kind === 156 /* ConstructSignature */);
+                        emitType(node.constraint);
+                    }
+                    else {
+                        emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError);
+                    }
+                }
+                if (node.default && !isPrivateMethodTypeParameter(node)) {
+                    write(" = ");
+                    if (node.parent.kind === 160 /* FunctionType */ ||
+                        node.parent.kind === 161 /* ConstructorType */ ||
+                        (node.parent.parent && node.parent.parent.kind === 163 /* TypeLiteral */)) {
+                        ts.Debug.assert(node.parent.kind === 151 /* MethodDeclaration */ ||
+                            node.parent.kind === 150 /* MethodSignature */ ||
+                            node.parent.kind === 160 /* FunctionType */ ||
+                            node.parent.kind === 161 /* ConstructorType */ ||
+                            node.parent.kind === 155 /* CallSignature */ ||
+                            node.parent.kind === 156 /* ConstructSignature */);
+                        emitType(node.default);
+                    }
+                    else {
+                        emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError);
+                    }
+                }
+                function getTypeParameterConstraintVisibilityError() {
+                    // Type parameter constraints are named by user so we should always be able to name it
+                    var diagnosticMessage;
+                    switch (node.parent.kind) {
+                        case 229 /* ClassDeclaration */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
+                            break;
+                        case 230 /* InterfaceDeclaration */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
+                            break;
+                        case 156 /* ConstructSignature */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
+                            break;
+                        case 155 /* CallSignature */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
+                            break;
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                            if (ts.hasModifier(node.parent, 32 /* Static */)) {
+                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
+                            }
+                            else if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
+                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
+                            }
+                            else {
+                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
+                            }
+                            break;
+                        case 228 /* FunctionDeclaration */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
+                            break;
+                        case 231 /* TypeAliasDeclaration */:
+                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
+                            break;
+                        default:
+                            ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
+                    }
+                    return {
+                        diagnosticMessage: diagnosticMessage,
+                        errorNode: node,
+                        typeName: node.name
+                    };
+                }
+            }
+            if (typeParameters) {
+                write("<");
+                emitCommaList(typeParameters, emitTypeParameter);
+                write(">");
+            }
+        }
+        function emitHeritageClause(typeReferences, isImplementsList) {
+            if (typeReferences) {
+                write(isImplementsList ? " implements " : " extends ");
+                emitCommaList(typeReferences, emitTypeOfTypeReference);
+            }
+            function emitTypeOfTypeReference(node) {
+                if (ts.isEntityNameExpression(node.expression)) {
+                    emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
+                }
+                else if (!isImplementsList && node.expression.kind === 95 /* NullKeyword */) {
+                    write("null");
+                }
+                function getHeritageClauseVisibilityError() {
+                    var diagnosticMessage;
+                    // Heritage clause is written by user so it can always be named
+                    if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
+                        // Class or Interface implemented/extended is inaccessible
+                        diagnosticMessage = isImplementsList ?
+                            ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
+                            ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
+                    }
+                    else {
+                        // interface is inaccessible
+                        diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
+                    }
+                    return {
+                        diagnosticMessage: diagnosticMessage,
+                        errorNode: node,
+                        typeName: ts.getNameOfDeclaration(node.parent.parent)
+                    };
+                }
+            }
+        }
+        function writeClassDeclaration(node) {
+            function emitParameterProperties(constructorDeclaration) {
+                if (constructorDeclaration) {
+                    ts.forEach(constructorDeclaration.parameters, function (param) {
+                        if (ts.hasModifier(param, 92 /* ParameterPropertyModifier */)) {
+                            emitPropertyDeclaration(param);
+                        }
+                    });
+                }
+            }
+            var prevEnclosingDeclaration = enclosingDeclaration;
+            enclosingDeclaration = node;
+            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
+            var tempVarName;
+            if (baseTypeNode && !ts.isEntityNameExpression(baseTypeNode.expression)) {
+                tempVarName = baseTypeNode.expression.kind === 95 /* NullKeyword */ ?
+                    "null" :
+                    emitTempVariableDeclaration(baseTypeNode.expression, node.name.escapedText + "_base", {
+                        diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
+                        errorNode: baseTypeNode,
+                        typeName: node.name
+                    }, !ts.findAncestor(node, function (n) { return n.kind === 233 /* ModuleDeclaration */; }));
+            }
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            if (ts.hasModifier(node, 128 /* Abstract */)) {
+                write("abstract ");
+            }
+            write("class ");
+            writeTextOfNode(currentText, node.name);
+            emitTypeParameters(node.typeParameters);
+            if (baseTypeNode) {
+                if (!ts.isEntityNameExpression(baseTypeNode.expression)) {
+                    write(" extends ");
+                    write(tempVarName);
+                    if (baseTypeNode.typeArguments) {
+                        write("<");
+                        emitCommaList(baseTypeNode.typeArguments, emitType);
+                        write(">");
+                    }
+                }
+                else {
+                    emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
+                }
+            }
+            emitHeritageClause(ts.getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
+            write(" {");
+            writeLine();
+            increaseIndent();
+            emitParameterProperties(ts.getFirstConstructorWithBody(node));
+            emitLines(node.members);
+            decreaseIndent();
+            write("}");
+            writeLine();
+            enclosingDeclaration = prevEnclosingDeclaration;
+        }
+        function writeInterfaceDeclaration(node) {
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            write("interface ");
+            writeTextOfNode(currentText, node.name);
+            var prevEnclosingDeclaration = enclosingDeclaration;
+            enclosingDeclaration = node;
+            emitTypeParameters(node.typeParameters);
+            var interfaceExtendsTypes = ts.filter(ts.getInterfaceBaseTypeNodes(node), function (base) { return ts.isEntityNameExpression(base.expression); });
+            if (interfaceExtendsTypes && interfaceExtendsTypes.length) {
+                emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false);
+            }
+            write(" {");
+            writeLine();
+            increaseIndent();
+            emitLines(node.members);
+            decreaseIndent();
+            write("}");
+            writeLine();
+            enclosingDeclaration = prevEnclosingDeclaration;
+        }
+        function emitPropertyDeclaration(node) {
+            if (ts.hasDynamicName(node)) {
+                return;
+            }
+            emitJsDocComments(node);
+            emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
+            emitVariableDeclaration(node);
+            write(";");
+            writeLine();
+        }
+        function emitVariableDeclaration(node) {
+            // If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
+            // so there is no check needed to see if declaration is visible
+            if (node.kind !== 226 /* VariableDeclaration */ || resolver.isDeclarationVisible(node)) {
+                if (ts.isBindingPattern(node.name)) {
+                    emitBindingPattern(node.name);
+                }
+                else {
+                    // If this node is a computed name, it can only be a symbol, because we've already skipped
+                    // it if it's not a well known symbol. In that case, the text of the name will be exactly
+                    // what we want, namely the name expression enclosed in brackets.
+                    writeTextOfNode(currentText, node.name);
+                    // If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
+                    // we don't want to emit property declaration with "?"
+                    if ((node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */ ||
+                        (node.kind === 146 /* Parameter */ && !ts.isParameterPropertyDeclaration(node))) && ts.hasQuestionToken(node)) {
+                        write("?");
+                    }
+                    if ((node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */) && node.parent.kind === 163 /* TypeLiteral */) {
+                        emitTypeOfVariableDeclarationFromTypeLiteral(node);
+                    }
+                    else if (resolver.isLiteralConstDeclaration(node)) {
+                        write(" = ");
+                        resolver.writeLiteralConstValue(node, writer);
+                    }
+                    else if (!ts.hasModifier(node, 8 /* Private */)) {
+                        writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
+                    }
+                }
+            }
+            function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
+                if (node.kind === 226 /* VariableDeclaration */) {
+                    return symbolAccessibilityResult.errorModuleName ?
+                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                            ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                            ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
+                        ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
+                }
+                else if (node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */ ||
+                    (node.kind === 146 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) {
+                    // TODO(jfreeman): Deal with computed properties in error reporting.
+                    if (ts.hasModifier(node, 32 /* Static */)) {
+                        return symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
+                    }
+                    else if (node.parent.kind === 229 /* ClassDeclaration */ || node.kind === 146 /* Parameter */) {
+                        return symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
+                    }
+                    else {
+                        // Interfaces cannot have types that cannot be named
+                        return symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
+                    }
+                }
+            }
+            function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
+                var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
+                return diagnosticMessage !== undefined ? {
+                    diagnosticMessage: diagnosticMessage,
+                    errorNode: node,
+                    typeName: node.name
+                } : undefined;
+            }
+            function emitBindingPattern(bindingPattern) {
+                // Only select non-omitted expression from the bindingPattern's elements.
+                // We have to do this to avoid emitting trailing commas.
+                // For example:
+                //      original: var [, c,,] = [ 2,3,4]
+                //      emitted: declare var c: number; // instead of declare var c:number, ;
+                var elements = [];
+                for (var _i = 0, _a = bindingPattern.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    if (element.kind !== 200 /* OmittedExpression */) {
+                        elements.push(element);
+                    }
+                }
+                emitCommaList(elements, emitBindingElement);
+            }
+            function emitBindingElement(bindingElement) {
+                function getBindingElementTypeVisibilityError(symbolAccessibilityResult) {
+                    var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
+                    return diagnosticMessage !== undefined ? {
+                        diagnosticMessage: diagnosticMessage,
+                        errorNode: bindingElement,
+                        typeName: bindingElement.name
+                    } : undefined;
+                }
+                if (bindingElement.name) {
+                    if (ts.isBindingPattern(bindingElement.name)) {
+                        emitBindingPattern(bindingElement.name);
+                    }
+                    else {
+                        writeTextOfNode(currentText, bindingElement.name);
+                        writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
+                    }
+                }
+            }
+        }
+        function emitTypeOfVariableDeclarationFromTypeLiteral(node) {
+            // if this is property of type literal,
+            // or is parameter of method/call/construct/index signature of type literal
+            // emit only if type is specified
+            if (node.type) {
+                write(": ");
+                emitType(node.type);
+            }
+        }
+        function isVariableStatementVisible(node) {
+            return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); });
+        }
+        function writeVariableStatement(node) {
+            // If binding pattern doesn't have name, then there is nothing to be emitted for declaration file i.e. const [,] = [1,2].
+            if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) {
+                return;
+            }
+            emitJsDocComments(node);
+            emitModuleElementDeclarationFlags(node);
+            if (ts.isLet(node.declarationList)) {
+                write("let ");
+            }
+            else if (ts.isConst(node.declarationList)) {
+                write("const ");
+            }
+            else {
+                write("var ");
+            }
+            emitCommaList(node.declarationList.declarations, emitVariableDeclaration, resolver.isDeclarationVisible);
+            write(";");
+            writeLine();
+        }
+        function emitAccessorDeclaration(node) {
+            if (ts.hasDynamicName(node)) {
+                return;
+            }
+            var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
+            var accessorWithTypeAnnotation;
+            if (node === accessors.firstAccessor) {
+                emitJsDocComments(accessors.getAccessor);
+                emitJsDocComments(accessors.setAccessor);
+                emitClassMemberDeclarationFlags(ts.getModifierFlags(node) | (accessors.setAccessor ? 0 : 64 /* Readonly */));
+                writeTextOfNode(currentText, node.name);
+                if (!ts.hasModifier(node, 8 /* Private */)) {
+                    accessorWithTypeAnnotation = node;
+                    var type = getTypeAnnotationFromAccessor(node);
+                    if (!type) {
+                        // couldn't get type for the first accessor, try the another one
+                        var anotherAccessor = node.kind === 153 /* GetAccessor */ ? accessors.setAccessor : accessors.getAccessor;
+                        type = getTypeAnnotationFromAccessor(anotherAccessor);
+                        if (type) {
+                            accessorWithTypeAnnotation = anotherAccessor;
+                        }
+                    }
+                    writeTypeOfDeclaration(node, type, getAccessorDeclarationTypeVisibilityError);
+                }
+                write(";");
+                writeLine();
+            }
+            function getTypeAnnotationFromAccessor(accessor) {
+                if (accessor) {
+                    return accessor.kind === 153 /* GetAccessor */
+                        ? accessor.type // Getter - return type
+                        : accessor.parameters.length > 0
+                            ? accessor.parameters[0].type // Setter parameter type
+                            : undefined;
+                }
+            }
+            function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
+                var diagnosticMessage;
+                if (accessorWithTypeAnnotation.kind === 154 /* SetAccessor */) {
+                    // Setters have to have type named and cannot infer it so, the type should always be named
+                    if (ts.hasModifier(accessorWithTypeAnnotation.parent, 32 /* Static */)) {
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1;
+                    }
+                    else {
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1;
+                    }
+                    return {
+                        diagnosticMessage: diagnosticMessage,
+                        errorNode: accessorWithTypeAnnotation.parameters[0],
+                        // TODO(jfreeman): Investigate why we are passing node.name instead of node.parameters[0].name
+                        typeName: accessorWithTypeAnnotation.name
+                    };
+                }
+                else {
+                    if (ts.hasModifier(accessorWithTypeAnnotation, 32 /* Static */)) {
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
+                                ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0;
+                    }
+                    else {
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
+                                ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0;
+                    }
+                    return {
+                        diagnosticMessage: diagnosticMessage,
+                        errorNode: accessorWithTypeAnnotation.name,
+                        typeName: undefined
+                    };
+                }
+            }
+        }
+        function writeFunctionDeclaration(node) {
+            if (ts.hasDynamicName(node)) {
+                return;
+            }
+            // If we are emitting Method/Constructor it isn't moduleElement and hence already determined to be emitting
+            // so no need to verify if the declaration is visible
+            if (!resolver.isImplementationOfOverload(node)) {
+                emitJsDocComments(node);
+                if (node.kind === 228 /* FunctionDeclaration */) {
+                    emitModuleElementDeclarationFlags(node);
+                }
+                else if (node.kind === 151 /* MethodDeclaration */ || node.kind === 152 /* Constructor */) {
+                    emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
+                }
+                if (node.kind === 228 /* FunctionDeclaration */) {
+                    write("function ");
+                    writeTextOfNode(currentText, node.name);
+                }
+                else if (node.kind === 152 /* Constructor */) {
+                    write("constructor");
+                }
+                else {
+                    writeTextOfNode(currentText, node.name);
+                    if (ts.hasQuestionToken(node)) {
+                        write("?");
+                    }
+                }
+                emitSignatureDeclaration(node);
+            }
+        }
+        function emitSignatureDeclarationWithJsDocComments(node) {
+            emitJsDocComments(node);
+            emitSignatureDeclaration(node);
+        }
+        function emitSignatureDeclaration(node) {
+            var prevEnclosingDeclaration = enclosingDeclaration;
+            enclosingDeclaration = node;
+            var closeParenthesizedFunctionType = false;
+            if (node.kind === 157 /* IndexSignature */) {
+                // Index signature can have readonly modifier
+                emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
+                write("[");
+            }
+            else {
+                if (node.kind === 152 /* Constructor */ && ts.hasModifier(node, 8 /* Private */)) {
+                    write("();");
+                    writeLine();
+                    return;
+                }
+                // Construct signature or constructor type write new Signature
+                if (node.kind === 156 /* ConstructSignature */ || node.kind === 161 /* ConstructorType */) {
+                    write("new ");
+                }
+                else if (node.kind === 160 /* FunctionType */) {
+                    var currentOutput = writer.getText();
+                    // Do not generate incorrect type when function type with type parameters is type argument
+                    // This could happen if user used space between two '<' making it error free
+                    // e.g var x: A< <Tany>(a: Tany)=>Tany>;
+                    if (node.typeParameters && currentOutput.charAt(currentOutput.length - 1) === "<") {
+                        closeParenthesizedFunctionType = true;
+                        write("(");
+                    }
+                }
+                emitTypeParameters(node.typeParameters);
+                write("(");
+            }
+            // Parameters
+            emitCommaList(node.parameters, emitParameterDeclaration);
+            if (node.kind === 157 /* IndexSignature */) {
+                write("]");
+            }
+            else {
+                write(")");
+            }
+            // If this is not a constructor and is not private, emit the return type
+            var isFunctionTypeOrConstructorType = node.kind === 160 /* FunctionType */ || node.kind === 161 /* ConstructorType */;
+            if (isFunctionTypeOrConstructorType || node.parent.kind === 163 /* TypeLiteral */) {
+                // Emit type literal signature return type only if specified
+                if (node.type) {
+                    write(isFunctionTypeOrConstructorType ? " => " : ": ");
+                    emitType(node.type);
+                }
+            }
+            else if (node.kind !== 152 /* Constructor */ && !ts.hasModifier(node, 8 /* Private */)) {
+                writeReturnTypeAtSignature(node, getReturnTypeVisibilityError);
+            }
+            enclosingDeclaration = prevEnclosingDeclaration;
+            if (!isFunctionTypeOrConstructorType) {
+                write(";");
+                writeLine();
+            }
+            else if (closeParenthesizedFunctionType) {
+                write(")");
+            }
+            function getReturnTypeVisibilityError(symbolAccessibilityResult) {
+                var diagnosticMessage;
+                switch (node.kind) {
+                    case 156 /* ConstructSignature */:
+                        // Interfaces cannot have return types that cannot be named
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
+                        break;
+                    case 155 /* CallSignature */:
+                        // Interfaces cannot have return types that cannot be named
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
+                        break;
+                    case 157 /* IndexSignature */:
+                        // Interfaces cannot have return types that cannot be named
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
+                        break;
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        if (ts.hasModifier(node, 32 /* Static */)) {
+                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                    ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
+                                    ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
+                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
+                        }
+                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
+                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                    ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
+                                    ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
+                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
+                        }
+                        else {
+                            // Interfaces cannot have return types that cannot be named
+                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                                ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
+                                ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
+                        }
+                        break;
+                    case 228 /* FunctionDeclaration */:
+                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
+                                ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
+                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
+                        break;
+                    default:
+                        ts.Debug.fail("This is unknown kind for signature: " + node.kind);
+                }
+                return {
+                    diagnosticMessage: diagnosticMessage,
+                    errorNode: node.name || node
+                };
+            }
+        }
+        function emitParameterDeclaration(node) {
+            increaseIndent();
+            emitJsDocComments(node);
+            if (node.dotDotDotToken) {
+                write("...");
+            }
+            if (ts.isBindingPattern(node.name)) {
+                // For bindingPattern, we can't simply writeTextOfNode from the source file
+                // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
+                // Therefore, we will have to recursively emit each element in the bindingPattern.
+                emitBindingPattern(node.name);
+            }
+            else {
+                writeTextOfNode(currentText, node.name);
+            }
+            if (resolver.isOptionalParameter(node)) {
+                write("?");
+            }
+            decreaseIndent();
+            if (node.parent.kind === 160 /* FunctionType */ ||
+                node.parent.kind === 161 /* ConstructorType */ ||
+                node.parent.parent.kind === 163 /* TypeLiteral */) {
+                emitTypeOfVariableDeclarationFromTypeLiteral(node);
+            }
+            else if (!ts.hasModifier(node.parent, 8 /* Private */)) {
+                writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError);
+            }
+            function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
+                var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
+                return diagnosticMessage !== undefined ? {
+                    diagnosticMessage: diagnosticMessage,
+                    errorNode: node,
+                    typeName: node.name
+                } : undefined;
+            }
+            function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
+                switch (node.parent.kind) {
+                    case 152 /* Constructor */:
+                        return symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
+                    case 156 /* ConstructSignature */:
+                        // Interfaces cannot have parameter types that cannot be named
+                        return symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
+                    case 155 /* CallSignature */:
+                        // Interfaces cannot have parameter types that cannot be named
+                        return symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
+                    case 157 /* IndexSignature */:
+                        // Interfaces cannot have parameter types that cannot be named
+                        return symbolAccessibilityResult.errorModuleName ?
+                            ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        if (ts.hasModifier(node.parent, 32 /* Static */)) {
+                            return symbolAccessibilityResult.errorModuleName ?
+                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                    ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                    ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
+                        }
+                        else if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
+                            return symbolAccessibilityResult.errorModuleName ?
+                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                    ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                    ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
+                        }
+                        else {
+                            // Interfaces cannot have parameter types that cannot be named
+                            return symbolAccessibilityResult.errorModuleName ?
+                                ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
+                                ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
+                        }
+                    case 228 /* FunctionDeclaration */:
+                        return symbolAccessibilityResult.errorModuleName ?
+                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
+                                ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+                                ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
+                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
+                    default:
+                        ts.Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
+                }
+            }
+            function emitBindingPattern(bindingPattern) {
+                // We have to explicitly emit square bracket and bracket because these tokens are not store inside the node.
+                if (bindingPattern.kind === 174 /* ObjectBindingPattern */) {
+                    write("{");
+                    emitCommaList(bindingPattern.elements, emitBindingElement);
+                    write("}");
+                }
+                else if (bindingPattern.kind === 175 /* ArrayBindingPattern */) {
+                    write("[");
+                    var elements = bindingPattern.elements;
+                    emitCommaList(elements, emitBindingElement);
+                    if (elements && elements.hasTrailingComma) {
+                        write(", ");
+                    }
+                    write("]");
+                }
+            }
+            function emitBindingElement(bindingElement) {
+                if (bindingElement.kind === 200 /* OmittedExpression */) {
+                    // If bindingElement is an omittedExpression (i.e. containing elision),
+                    // we will emit blank space (although this may differ from users' original code,
+                    // it allows emitSeparatedList to write separator appropriately)
+                    // Example:
+                    //      original: function foo([, x, ,]) {}
+                    //      emit    : function foo([ , x,  , ]) {}
+                    write(" ");
+                }
+                else if (bindingElement.kind === 176 /* BindingElement */) {
+                    if (bindingElement.propertyName) {
+                        // bindingElement has propertyName property in the following case:
+                        //      { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y"
+                        // We have to explicitly emit the propertyName before descending into its binding elements.
+                        // Example:
+                        //      original: function foo({y: [a,b,c]}) {}
+                        //      emit    : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
+                        writeTextOfNode(currentText, bindingElement.propertyName);
+                        write(": ");
+                    }
+                    if (bindingElement.name) {
+                        if (ts.isBindingPattern(bindingElement.name)) {
+                            // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
+                            // In the case of rest element, we will omit rest element.
+                            // Example:
+                            //      original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {}
+                            //      emit    : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
+                            //      original with rest: function foo([a, ...c]) {}
+                            //      emit              : declare function foo([a, ...c]): void;
+                            emitBindingPattern(bindingElement.name);
+                        }
+                        else {
+                            ts.Debug.assert(bindingElement.name.kind === 71 /* Identifier */);
+                            // If the node is just an identifier, we will simply emit the text associated with the node's name
+                            // Example:
+                            //      original: function foo({y = 10, x}) {}
+                            //      emit    : declare function foo({y, x}: {number, any}): void;
+                            if (bindingElement.dotDotDotToken) {
+                                write("...");
+                            }
+                            writeTextOfNode(currentText, bindingElement.name);
+                        }
+                    }
+                }
+            }
+        }
+        function emitNode(node) {
+            switch (node.kind) {
+                case 228 /* FunctionDeclaration */:
+                case 233 /* ModuleDeclaration */:
+                case 237 /* ImportEqualsDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                case 229 /* ClassDeclaration */:
+                case 231 /* TypeAliasDeclaration */:
+                case 232 /* EnumDeclaration */:
+                    return emitModuleElement(node, isModuleElementVisible(node));
+                case 208 /* VariableStatement */:
+                    return emitModuleElement(node, isVariableStatementVisible(node));
+                case 238 /* ImportDeclaration */:
+                    // Import declaration without import clause is visible, otherwise it is not visible
+                    return emitModuleElement(node, /*isModuleElementVisible*/ !node.importClause);
+                case 244 /* ExportDeclaration */:
+                    return emitExportDeclaration(node);
+                case 152 /* Constructor */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                    return writeFunctionDeclaration(node);
+                case 156 /* ConstructSignature */:
+                case 155 /* CallSignature */:
+                case 157 /* IndexSignature */:
+                    return emitSignatureDeclarationWithJsDocComments(node);
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return emitAccessorDeclaration(node);
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    return emitPropertyDeclaration(node);
+                case 264 /* EnumMember */:
+                    return emitEnumMemberDeclaration(node);
+                case 243 /* ExportAssignment */:
+                    return emitExportAssignment(node);
+                case 265 /* SourceFile */:
+                    return emitSourceFile(node);
+            }
+        }
+        /**
+         * Adds the reference to referenced file, returns true if global file reference was emitted
+         * @param referencedFile
+         * @param addBundledFileReference Determines if global file reference corresponding to bundled file should be emitted or not
+         */
+        function writeReferencePath(referencedFile, addBundledFileReference, emitOnlyDtsFiles) {
+            var declFileName;
+            var addedBundledEmitReference = false;
+            if (referencedFile.isDeclarationFile) {
+                // Declaration file, use declaration file name
+                declFileName = referencedFile.fileName;
+            }
+            else {
+                // Get the declaration file path
+                ts.forEachEmittedFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles);
+            }
+            if (declFileName) {
+                declFileName = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizeSlashes(declarationFilePath)), declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
+                /*isAbsolutePathAnUrl*/ false);
+                referencesOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
+            }
+            return addedBundledEmitReference;
+            function getDeclFileName(emitFileNames, sourceFileOrBundle) {
+                // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
+                var isBundledEmit = sourceFileOrBundle.kind === 266 /* Bundle */;
+                if (isBundledEmit && !addBundledFileReference) {
+                    return;
+                }
+                ts.Debug.assert(!!emitFileNames.declarationFilePath || ts.isSourceFileJavaScript(referencedFile), "Declaration file is not present only for javascript files");
+                declFileName = emitFileNames.declarationFilePath || emitFileNames.jsFilePath;
+                addedBundledEmitReference = isBundledEmit;
+            }
+        }
+    }
+    /* @internal */
+    function writeDeclarationFile(declarationFilePath, sourceFileOrBundle, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) {
+        var emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
+        var emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
+        if (!emitSkipped) {
+            var sourceFiles = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
+            var declarationOutput = emitDeclarationResult.referencesOutput
+                + getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
+            ts.writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);
+        }
+        return emitSkipped;
+        function getDeclarationOutput(synchronousDeclarationOutput, moduleElementDeclarationEmitInfo) {
+            var appliedSyncOutputPos = 0;
+            var declarationOutput = "";
+            // apply asynchronous additions to the synchronous output
+            ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+                if (aliasEmitInfo.asynchronousOutput) {
+                    declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos, aliasEmitInfo.outputPos);
+                    declarationOutput += getDeclarationOutput(aliasEmitInfo.asynchronousOutput, aliasEmitInfo.subModuleElementDeclarationEmitInfo);
+                    appliedSyncOutputPos = aliasEmitInfo.outputPos;
+                }
+            });
+            declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos);
+            return declarationOutput;
+        }
+    }
+    ts.writeDeclarationFile = writeDeclarationFile;
+})(ts || (ts = {}));
+/// <reference path="checker.ts" />
+/// <reference path="transformer.ts" />
+/// <reference path="declarationEmitter.ts" />
+/// <reference path="sourcemap.ts" />
+/// <reference path="comments.ts" />
+var ts;
+(function (ts) {
+    var delimiters = createDelimiterMap();
+    var brackets = createBracketsMap();
+    /*@internal*/
+    /**
+     * Iterates over the source files that are expected to have an emit output.
+     *
+     * @param host An EmitHost.
+     * @param action The action to execute.
+     * @param sourceFilesOrTargetSourceFile
+     *   If an array, the full list of source files to emit.
+     *   Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
+     */
+    function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, emitOnlyDtsFiles) {
+        var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
+        var options = host.getCompilerOptions();
+        if (options.outFile || options.out) {
+            if (sourceFiles.length) {
+                var jsFilePath = options.outFile || options.out;
+                var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
+                var declarationFilePath = options.declaration ? ts.removeFileExtension(jsFilePath) + ".d.ts" /* Dts */ : "";
+                action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, ts.createBundle(sourceFiles), emitOnlyDtsFiles);
+            }
+        }
+        else {
+            for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) {
+                var sourceFile = sourceFiles_1[_a];
+                var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
+                var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
+                var declarationFilePath = !ts.isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? ts.getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
+                action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, sourceFile, emitOnlyDtsFiles);
+            }
+        }
+    }
+    ts.forEachEmittedFile = forEachEmittedFile;
+    function getSourceMapFilePath(jsFilePath, options) {
+        return options.sourceMap ? jsFilePath + ".map" : undefined;
+    }
+    // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
+    // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
+    // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
+    function getOutputExtension(sourceFile, options) {
+        if (options.jsx === 1 /* Preserve */) {
+            if (ts.isSourceFileJavaScript(sourceFile)) {
+                if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) {
+                    return ".jsx" /* Jsx */;
+                }
+            }
+            else if (sourceFile.languageVariant === 1 /* JSX */) {
+                // TypeScript source file preserving JSX syntax
+                return ".jsx" /* Jsx */;
+            }
+        }
+        return ".js" /* Js */;
+    }
+    function getOriginalSourceFileOrBundle(sourceFileOrBundle) {
+        if (sourceFileOrBundle.kind === 266 /* Bundle */) {
+            return ts.updateBundle(sourceFileOrBundle, ts.sameMap(sourceFileOrBundle.sourceFiles, ts.getOriginalSourceFile));
+        }
+        return ts.getOriginalSourceFile(sourceFileOrBundle);
+    }
+    /*@internal*/
+    // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
+    function emitFiles(resolver, host, targetSourceFile, emitOnlyDtsFiles, transformers) {
+        var compilerOptions = host.getCompilerOptions();
+        var moduleKind = ts.getEmitModuleKind(compilerOptions);
+        var sourceMapDataList = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
+        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
+        var emitterDiagnostics = ts.createDiagnosticCollection();
+        var newLine = host.getNewLine();
+        var writer = ts.createTextWriter(newLine);
+        var sourceMap = ts.createSourceMapWriter(host, writer);
+        var currentSourceFile;
+        var bundledHelpers;
+        var isOwnFileEmit;
+        var emitSkipped = false;
+        var sourceFiles = ts.getSourceFilesToEmit(host, targetSourceFile);
+        // Transform the source files
+        var transform = ts.transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
+        // Create a printer to print the nodes
+        var printer = createPrinter(compilerOptions, {
+            // resolver hooks
+            hasGlobalName: resolver.hasGlobalName,
+            // transform hooks
+            onEmitNode: transform.emitNodeWithNotification,
+            substituteNode: transform.substituteNode,
+            // sourcemap hooks
+            onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
+            onEmitSourceMapOfToken: sourceMap.emitTokenWithSourceMap,
+            onEmitSourceMapOfPosition: sourceMap.emitPos,
+            // emitter hooks
+            onEmitHelpers: emitHelpers,
+            onSetSourceFile: setSourceFile,
+        });
+        // Emit each output file
+        ts.performance.mark("beforePrint");
+        forEachEmittedFile(host, emitSourceFileOrBundle, transform.transformed, emitOnlyDtsFiles);
+        ts.performance.measure("printTime", "beforePrint");
+        // Clean up emit nodes on parse tree
+        transform.dispose();
+        return {
+            emitSkipped: emitSkipped,
+            diagnostics: emitterDiagnostics.getDiagnostics(),
+            emittedFiles: emittedFilesList,
+            sourceMaps: sourceMapDataList
+        };
+        function emitSourceFileOrBundle(_a, sourceFileOrBundle) {
+            var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath;
+            // Make sure not to write js file and source map file if any of them cannot be written
+            if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) {
+                if (!emitOnlyDtsFiles) {
+                    printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
+                }
+            }
+            else {
+                emitSkipped = true;
+            }
+            if (declarationFilePath) {
+                emitSkipped = ts.writeDeclarationFile(declarationFilePath, getOriginalSourceFileOrBundle(sourceFileOrBundle), host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped;
+            }
+            if (!emitSkipped && emittedFilesList) {
+                if (!emitOnlyDtsFiles) {
+                    emittedFilesList.push(jsFilePath);
+                }
+                if (sourceMapFilePath) {
+                    emittedFilesList.push(sourceMapFilePath);
+                }
+                if (declarationFilePath) {
+                    emittedFilesList.push(declarationFilePath);
+                }
+            }
+        }
+        function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle) {
+            var bundle = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle : undefined;
+            var sourceFile = sourceFileOrBundle.kind === 265 /* SourceFile */ ? sourceFileOrBundle : undefined;
+            var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
+            sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
+            if (bundle) {
+                bundledHelpers = ts.createMap();
+                isOwnFileEmit = false;
+                printer.writeBundle(bundle, writer);
+            }
+            else {
+                isOwnFileEmit = true;
+                printer.writeFile(sourceFile, writer);
+            }
+            writer.writeLine();
+            var sourceMappingURL = sourceMap.getSourceMappingURL();
+            if (sourceMappingURL) {
+                writer.write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Sometimes tools can sometimes see this line as a source mapping url comment
+            }
+            // Write the source map
+            if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
+                ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
+            }
+            // Record source map data for the test harness.
+            if (sourceMapDataList) {
+                sourceMapDataList.push(sourceMap.getSourceMapData());
+            }
+            // Write the output file
+            ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
+            // Reset state
+            sourceMap.reset();
+            writer.reset();
+            currentSourceFile = undefined;
+            bundledHelpers = undefined;
+            isOwnFileEmit = false;
+        }
+        function setSourceFile(node) {
+            currentSourceFile = node;
+            sourceMap.setSourceFile(node);
+        }
+        function emitHelpers(node, writeLines) {
+            var helpersEmitted = false;
+            var bundle = node.kind === 266 /* Bundle */ ? node : undefined;
+            if (bundle && moduleKind === ts.ModuleKind.None) {
+                return;
+            }
+            var numNodes = bundle ? bundle.sourceFiles.length : 1;
+            for (var i = 0; i < numNodes; i++) {
+                var currentNode = bundle ? bundle.sourceFiles[i] : node;
+                var sourceFile = ts.isSourceFile(currentNode) ? currentNode : currentSourceFile;
+                var shouldSkip = compilerOptions.noEmitHelpers || ts.getExternalHelpersModuleName(sourceFile) !== undefined;
+                var shouldBundle = ts.isSourceFile(currentNode) && !isOwnFileEmit;
+                var helpers = ts.getEmitHelpers(currentNode);
+                if (helpers) {
+                    for (var _a = 0, _b = ts.stableSort(helpers, ts.compareEmitHelpers); _a < _b.length; _a++) {
+                        var helper = _b[_a];
+                        if (!helper.scoped) {
+                            // Skip the helper if it can be skipped and the noEmitHelpers compiler
+                            // option is set, or if it can be imported and the importHelpers compiler
+                            // option is set.
+                            if (shouldSkip)
+                                continue;
+                            // Skip the helper if it can be bundled but hasn't already been emitted and we
+                            // are emitting a bundled module.
+                            if (shouldBundle) {
+                                if (bundledHelpers.get(helper.name)) {
+                                    continue;
+                                }
+                                bundledHelpers.set(helper.name, true);
+                            }
+                        }
+                        else if (bundle) {
+                            // Skip the helper if it is scoped and we are emitting bundled helpers
+                            continue;
+                        }
+                        writeLines(helper.text);
+                        helpersEmitted = true;
+                    }
+                }
+            }
+            return helpersEmitted;
+        }
+    }
+    ts.emitFiles = emitFiles;
+    function createPrinter(printerOptions, handlers) {
+        if (printerOptions === void 0) { printerOptions = {}; }
+        if (handlers === void 0) { handlers = {}; }
+        var hasGlobalName = handlers.hasGlobalName, onEmitSourceMapOfNode = handlers.onEmitSourceMapOfNode, onEmitSourceMapOfToken = handlers.onEmitSourceMapOfToken, onEmitSourceMapOfPosition = handlers.onEmitSourceMapOfPosition, onEmitNode = handlers.onEmitNode, onEmitHelpers = handlers.onEmitHelpers, onSetSourceFile = handlers.onSetSourceFile, substituteNode = handlers.substituteNode, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken;
+        var newLine = ts.getNewLineCharacter(printerOptions);
+        var comments = ts.createCommentWriter(printerOptions, onEmitSourceMapOfPosition);
+        var emitNodeWithComments = comments.emitNodeWithComments, emitBodyWithDetachedComments = comments.emitBodyWithDetachedComments, emitTrailingCommentsOfPosition = comments.emitTrailingCommentsOfPosition, emitLeadingCommentsOfPosition = comments.emitLeadingCommentsOfPosition;
+        var currentSourceFile;
+        var nodeIdToGeneratedName; // Map of generated names for specific nodes.
+        var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
+        var generatedNames; // Set of names generated by the NameGenerator.
+        var tempFlagsStack; // Stack of enclosing name generation scopes.
+        var tempFlags; // TempFlags for the current name generation scope.
+        var writer;
+        var ownWriter;
+        reset();
+        return {
+            // public API
+            printNode: printNode,
+            printFile: printFile,
+            printBundle: printBundle,
+            // internal API
+            writeNode: writeNode,
+            writeFile: writeFile,
+            writeBundle: writeBundle
+        };
+        function printNode(hint, node, sourceFile) {
+            switch (hint) {
+                case 0 /* SourceFile */:
+                    ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node.");
+                    break;
+                case 2 /* IdentifierName */:
+                    ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node.");
+                    break;
+                case 1 /* Expression */:
+                    ts.Debug.assert(ts.isExpression(node), "Expected an Expression node.");
+                    break;
+            }
+            switch (node.kind) {
+                case 265 /* SourceFile */: return printFile(node);
+                case 266 /* Bundle */: return printBundle(node);
+            }
+            writeNode(hint, node, sourceFile, beginPrint());
+            return endPrint();
+        }
+        function printBundle(bundle) {
+            writeBundle(bundle, beginPrint());
+            return endPrint();
+        }
+        function printFile(sourceFile) {
+            writeFile(sourceFile, beginPrint());
+            return endPrint();
+        }
+        function writeNode(hint, node, sourceFile, output) {
+            var previousWriter = writer;
+            setWriter(output);
+            print(hint, node, sourceFile);
+            reset();
+            writer = previousWriter;
+        }
+        function writeBundle(bundle, output) {
+            var previousWriter = writer;
+            setWriter(output);
+            emitShebangIfNeeded(bundle);
+            emitPrologueDirectivesIfNeeded(bundle);
+            emitHelpersIndirect(bundle);
+            for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) {
+                var sourceFile = _b[_a];
+                print(0 /* SourceFile */, sourceFile, sourceFile);
+            }
+            reset();
+            writer = previousWriter;
+        }
+        function writeFile(sourceFile, output) {
+            var previousWriter = writer;
+            setWriter(output);
+            emitShebangIfNeeded(sourceFile);
+            emitPrologueDirectivesIfNeeded(sourceFile);
+            print(0 /* SourceFile */, sourceFile, sourceFile);
+            reset();
+            writer = previousWriter;
+        }
+        function beginPrint() {
+            return ownWriter || (ownWriter = ts.createTextWriter(newLine));
+        }
+        function endPrint() {
+            var text = ownWriter.getText();
+            ownWriter.reset();
+            return text;
+        }
+        function print(hint, node, sourceFile) {
+            if (sourceFile) {
+                setSourceFile(sourceFile);
+            }
+            pipelineEmitWithNotification(hint, node);
+        }
+        function setSourceFile(sourceFile) {
+            currentSourceFile = sourceFile;
+            comments.setSourceFile(sourceFile);
+            if (onSetSourceFile) {
+                onSetSourceFile(sourceFile);
+            }
+        }
+        function setWriter(output) {
+            writer = output;
+            comments.setWriter(output);
+        }
+        function reset() {
+            nodeIdToGeneratedName = [];
+            autoGeneratedIdToGeneratedName = [];
+            generatedNames = ts.createMap();
+            tempFlagsStack = [];
+            tempFlags = 0 /* Auto */;
+            comments.reset();
+            setWriter(/*output*/ undefined);
+        }
+        // TODO: Should this just be `emit`?
+        // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034
+        function emitIfPresent(node) {
+            if (node) {
+                emit(node);
+            }
+        }
+        function emit(node) {
+            pipelineEmitWithNotification(4 /* Unspecified */, node);
+        }
+        function emitIdentifierName(node) {
+            pipelineEmitWithNotification(2 /* IdentifierName */, node);
+        }
+        function emitExpression(node) {
+            pipelineEmitWithNotification(1 /* Expression */, node);
+        }
+        function pipelineEmitWithNotification(hint, node) {
+            if (onEmitNode) {
+                onEmitNode(hint, node, pipelineEmitWithComments);
+            }
+            else {
+                pipelineEmitWithComments(hint, node);
+            }
+        }
+        function pipelineEmitWithComments(hint, node) {
+            node = trySubstituteNode(hint, node);
+            if (emitNodeWithComments && hint !== 0 /* SourceFile */) {
+                emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
+            }
+            else {
+                pipelineEmitWithSourceMap(hint, node);
+            }
+        }
+        function pipelineEmitWithSourceMap(hint, node) {
+            if (onEmitSourceMapOfNode && hint !== 0 /* SourceFile */ && hint !== 2 /* IdentifierName */) {
+                onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
+            }
+            else {
+                pipelineEmitWithHint(hint, node);
+            }
+        }
+        function pipelineEmitWithHint(hint, node) {
+            switch (hint) {
+                case 0 /* SourceFile */: return pipelineEmitSourceFile(node);
+                case 2 /* IdentifierName */: return pipelineEmitIdentifierName(node);
+                case 1 /* Expression */: return pipelineEmitExpression(node);
+                case 3 /* MappedTypeParameter */: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration));
+                case 4 /* Unspecified */: return pipelineEmitUnspecified(node);
+            }
+        }
+        function pipelineEmitSourceFile(node) {
+            ts.Debug.assertNode(node, ts.isSourceFile);
+            emitSourceFile(node);
+        }
+        function pipelineEmitIdentifierName(node) {
+            ts.Debug.assertNode(node, ts.isIdentifier);
+            emitIdentifier(node);
+        }
+        function emitMappedTypeParameter(node) {
+            emit(node.name);
+            write(" in ");
+            emit(node.constraint);
+        }
+        function pipelineEmitUnspecified(node) {
+            var kind = node.kind;
+            // Reserved words
+            // Strict mode reserved words
+            // Contextual keywords
+            if (ts.isKeyword(kind)) {
+                writeTokenNode(node);
+                return;
+            }
+            switch (kind) {
+                // Pseudo-literals
+                case 14 /* TemplateHead */:
+                case 15 /* TemplateMiddle */:
+                case 16 /* TemplateTail */:
+                    return emitLiteral(node);
+                // Identifiers
+                case 71 /* Identifier */:
+                    return emitIdentifier(node);
+                // Parse tree nodes
+                // Names
+                case 143 /* QualifiedName */:
+                    return emitQualifiedName(node);
+                case 144 /* ComputedPropertyName */:
+                    return emitComputedPropertyName(node);
+                // Signature elements
+                case 145 /* TypeParameter */:
+                    return emitTypeParameter(node);
+                case 146 /* Parameter */:
+                    return emitParameter(node);
+                case 147 /* Decorator */:
+                    return emitDecorator(node);
+                // Type members
+                case 148 /* PropertySignature */:
+                    return emitPropertySignature(node);
+                case 149 /* PropertyDeclaration */:
+                    return emitPropertyDeclaration(node);
+                case 150 /* MethodSignature */:
+                    return emitMethodSignature(node);
+                case 151 /* MethodDeclaration */:
+                    return emitMethodDeclaration(node);
+                case 152 /* Constructor */:
+                    return emitConstructor(node);
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return emitAccessorDeclaration(node);
+                case 155 /* CallSignature */:
+                    return emitCallSignature(node);
+                case 156 /* ConstructSignature */:
+                    return emitConstructSignature(node);
+                case 157 /* IndexSignature */:
+                    return emitIndexSignature(node);
+                // Types
+                case 158 /* TypePredicate */:
+                    return emitTypePredicate(node);
+                case 159 /* TypeReference */:
+                    return emitTypeReference(node);
+                case 160 /* FunctionType */:
+                    return emitFunctionType(node);
+                case 273 /* JSDocFunctionType */:
+                    return emitJSDocFunctionType(node);
+                case 161 /* ConstructorType */:
+                    return emitConstructorType(node);
+                case 162 /* TypeQuery */:
+                    return emitTypeQuery(node);
+                case 163 /* TypeLiteral */:
+                    return emitTypeLiteral(node);
+                case 164 /* ArrayType */:
+                    return emitArrayType(node);
+                case 165 /* TupleType */:
+                    return emitTupleType(node);
+                case 166 /* UnionType */:
+                    return emitUnionType(node);
+                case 167 /* IntersectionType */:
+                    return emitIntersectionType(node);
+                case 168 /* ParenthesizedType */:
+                    return emitParenthesizedType(node);
+                case 201 /* ExpressionWithTypeArguments */:
+                    return emitExpressionWithTypeArguments(node);
+                case 169 /* ThisType */:
+                    return emitThisType();
+                case 170 /* TypeOperator */:
+                    return emitTypeOperator(node);
+                case 171 /* IndexedAccessType */:
+                    return emitIndexedAccessType(node);
+                case 172 /* MappedType */:
+                    return emitMappedType(node);
+                case 173 /* LiteralType */:
+                    return emitLiteralType(node);
+                case 268 /* JSDocAllType */:
+                    write("*");
+                    return;
+                case 269 /* JSDocUnknownType */:
+                    write("?");
+                    return;
+                case 270 /* JSDocNullableType */:
+                    return emitJSDocNullableType(node);
+                case 271 /* JSDocNonNullableType */:
+                    return emitJSDocNonNullableType(node);
+                case 272 /* JSDocOptionalType */:
+                    return emitJSDocOptionalType(node);
+                case 274 /* JSDocVariadicType */:
+                    return emitJSDocVariadicType(node);
+                // Binding patterns
+                case 174 /* ObjectBindingPattern */:
+                    return emitObjectBindingPattern(node);
+                case 175 /* ArrayBindingPattern */:
+                    return emitArrayBindingPattern(node);
+                case 176 /* BindingElement */:
+                    return emitBindingElement(node);
+                // Misc
+                case 205 /* TemplateSpan */:
+                    return emitTemplateSpan(node);
+                case 206 /* SemicolonClassElement */:
+                    return emitSemicolonClassElement();
+                // Statements
+                case 207 /* Block */:
+                    return emitBlock(node);
+                case 208 /* VariableStatement */:
+                    return emitVariableStatement(node);
+                case 209 /* EmptyStatement */:
+                    return emitEmptyStatement();
+                case 210 /* ExpressionStatement */:
+                    return emitExpressionStatement(node);
+                case 211 /* IfStatement */:
+                    return emitIfStatement(node);
+                case 212 /* DoStatement */:
+                    return emitDoStatement(node);
+                case 213 /* WhileStatement */:
+                    return emitWhileStatement(node);
+                case 214 /* ForStatement */:
+                    return emitForStatement(node);
+                case 215 /* ForInStatement */:
+                    return emitForInStatement(node);
+                case 216 /* ForOfStatement */:
+                    return emitForOfStatement(node);
+                case 217 /* ContinueStatement */:
+                    return emitContinueStatement(node);
+                case 218 /* BreakStatement */:
+                    return emitBreakStatement(node);
+                case 219 /* ReturnStatement */:
+                    return emitReturnStatement(node);
+                case 220 /* WithStatement */:
+                    return emitWithStatement(node);
+                case 221 /* SwitchStatement */:
+                    return emitSwitchStatement(node);
+                case 222 /* LabeledStatement */:
+                    return emitLabeledStatement(node);
+                case 223 /* ThrowStatement */:
+                    return emitThrowStatement(node);
+                case 224 /* TryStatement */:
+                    return emitTryStatement(node);
+                case 225 /* DebuggerStatement */:
+                    return emitDebuggerStatement(node);
+                // Declarations
+                case 226 /* VariableDeclaration */:
+                    return emitVariableDeclaration(node);
+                case 227 /* VariableDeclarationList */:
+                    return emitVariableDeclarationList(node);
+                case 228 /* FunctionDeclaration */:
+                    return emitFunctionDeclaration(node);
+                case 229 /* ClassDeclaration */:
+                    return emitClassDeclaration(node);
+                case 230 /* InterfaceDeclaration */:
+                    return emitInterfaceDeclaration(node);
+                case 231 /* TypeAliasDeclaration */:
+                    return emitTypeAliasDeclaration(node);
+                case 232 /* EnumDeclaration */:
+                    return emitEnumDeclaration(node);
+                case 233 /* ModuleDeclaration */:
+                    return emitModuleDeclaration(node);
+                case 234 /* ModuleBlock */:
+                    return emitModuleBlock(node);
+                case 235 /* CaseBlock */:
+                    return emitCaseBlock(node);
+                case 236 /* NamespaceExportDeclaration */:
+                    return emitNamespaceExportDeclaration(node);
+                case 237 /* ImportEqualsDeclaration */:
+                    return emitImportEqualsDeclaration(node);
+                case 238 /* ImportDeclaration */:
+                    return emitImportDeclaration(node);
+                case 239 /* ImportClause */:
+                    return emitImportClause(node);
+                case 240 /* NamespaceImport */:
+                    return emitNamespaceImport(node);
+                case 241 /* NamedImports */:
+                    return emitNamedImports(node);
+                case 242 /* ImportSpecifier */:
+                    return emitImportSpecifier(node);
+                case 243 /* ExportAssignment */:
+                    return emitExportAssignment(node);
+                case 244 /* ExportDeclaration */:
+                    return emitExportDeclaration(node);
+                case 245 /* NamedExports */:
+                    return emitNamedExports(node);
+                case 246 /* ExportSpecifier */:
+                    return emitExportSpecifier(node);
+                case 247 /* MissingDeclaration */:
+                    return;
+                // Module references
+                case 248 /* ExternalModuleReference */:
+                    return emitExternalModuleReference(node);
+                // JSX (non-expression)
+                case 10 /* JsxText */:
+                    return emitJsxText(node);
+                case 251 /* JsxOpeningElement */:
+                    return emitJsxOpeningElement(node);
+                case 252 /* JsxClosingElement */:
+                    return emitJsxClosingElement(node);
+                case 253 /* JsxAttribute */:
+                    return emitJsxAttribute(node);
+                case 254 /* JsxAttributes */:
+                    return emitJsxAttributes(node);
+                case 255 /* JsxSpreadAttribute */:
+                    return emitJsxSpreadAttribute(node);
+                case 256 /* JsxExpression */:
+                    return emitJsxExpression(node);
+                // Clauses
+                case 257 /* CaseClause */:
+                    return emitCaseClause(node);
+                case 258 /* DefaultClause */:
+                    return emitDefaultClause(node);
+                case 259 /* HeritageClause */:
+                    return emitHeritageClause(node);
+                case 260 /* CatchClause */:
+                    return emitCatchClause(node);
+                // Property assignments
+                case 261 /* PropertyAssignment */:
+                    return emitPropertyAssignment(node);
+                case 262 /* ShorthandPropertyAssignment */:
+                    return emitShorthandPropertyAssignment(node);
+                case 263 /* SpreadAssignment */:
+                    return emitSpreadAssignment(node);
+                // Enum
+                case 264 /* EnumMember */:
+                    return emitEnumMember(node);
+            }
+            // If the node is an expression, try to emit it as an expression with
+            // substitution.
+            if (ts.isExpression(node)) {
+                return pipelineEmitExpression(trySubstituteNode(1 /* Expression */, node));
+            }
+            if (ts.isToken(node)) {
+                writeTokenNode(node);
+                return;
+            }
+        }
+        function pipelineEmitExpression(node) {
+            var kind = node.kind;
+            switch (kind) {
+                // Literals
+                case 8 /* NumericLiteral */:
+                    return emitNumericLiteral(node);
+                case 9 /* StringLiteral */:
+                case 12 /* RegularExpressionLiteral */:
+                case 13 /* NoSubstitutionTemplateLiteral */:
+                    return emitLiteral(node);
+                // Identifiers
+                case 71 /* Identifier */:
+                    return emitIdentifier(node);
+                // Reserved words
+                case 86 /* FalseKeyword */:
+                case 95 /* NullKeyword */:
+                case 97 /* SuperKeyword */:
+                case 101 /* TrueKeyword */:
+                case 99 /* ThisKeyword */:
+                case 91 /* ImportKeyword */:
+                    writeTokenNode(node);
+                    return;
+                // Expressions
+                case 177 /* ArrayLiteralExpression */:
+                    return emitArrayLiteralExpression(node);
+                case 178 /* ObjectLiteralExpression */:
+                    return emitObjectLiteralExpression(node);
+                case 179 /* PropertyAccessExpression */:
+                    return emitPropertyAccessExpression(node);
+                case 180 /* ElementAccessExpression */:
+                    return emitElementAccessExpression(node);
+                case 181 /* CallExpression */:
+                    return emitCallExpression(node);
+                case 182 /* NewExpression */:
+                    return emitNewExpression(node);
+                case 183 /* TaggedTemplateExpression */:
+                    return emitTaggedTemplateExpression(node);
+                case 184 /* TypeAssertionExpression */:
+                    return emitTypeAssertionExpression(node);
+                case 185 /* ParenthesizedExpression */:
+                    return emitParenthesizedExpression(node);
+                case 186 /* FunctionExpression */:
+                    return emitFunctionExpression(node);
+                case 187 /* ArrowFunction */:
+                    return emitArrowFunction(node);
+                case 188 /* DeleteExpression */:
+                    return emitDeleteExpression(node);
+                case 189 /* TypeOfExpression */:
+                    return emitTypeOfExpression(node);
+                case 190 /* VoidExpression */:
+                    return emitVoidExpression(node);
+                case 191 /* AwaitExpression */:
+                    return emitAwaitExpression(node);
+                case 192 /* PrefixUnaryExpression */:
+                    return emitPrefixUnaryExpression(node);
+                case 193 /* PostfixUnaryExpression */:
+                    return emitPostfixUnaryExpression(node);
+                case 194 /* BinaryExpression */:
+                    return emitBinaryExpression(node);
+                case 195 /* ConditionalExpression */:
+                    return emitConditionalExpression(node);
+                case 196 /* TemplateExpression */:
+                    return emitTemplateExpression(node);
+                case 197 /* YieldExpression */:
+                    return emitYieldExpression(node);
+                case 198 /* SpreadElement */:
+                    return emitSpreadExpression(node);
+                case 199 /* ClassExpression */:
+                    return emitClassExpression(node);
+                case 200 /* OmittedExpression */:
+                    return;
+                case 202 /* AsExpression */:
+                    return emitAsExpression(node);
+                case 203 /* NonNullExpression */:
+                    return emitNonNullExpression(node);
+                case 204 /* MetaProperty */:
+                    return emitMetaProperty(node);
+                // JSX
+                case 249 /* JsxElement */:
+                    return emitJsxElement(node);
+                case 250 /* JsxSelfClosingElement */:
+                    return emitJsxSelfClosingElement(node);
+                // Transformation nodes
+                case 288 /* PartiallyEmittedExpression */:
+                    return emitPartiallyEmittedExpression(node);
+                case 289 /* CommaListExpression */:
+                    return emitCommaList(node);
+            }
+        }
+        function trySubstituteNode(hint, node) {
+            return node && substituteNode && substituteNode(hint, node) || node;
+        }
+        function emitHelpersIndirect(node) {
+            if (onEmitHelpers) {
+                onEmitHelpers(node, writeLines);
+            }
+        }
+        //
+        // Literals/Pseudo-literals
+        //
+        // SyntaxKind.NumericLiteral
+        function emitNumericLiteral(node) {
+            emitLiteral(node);
+        }
+        // SyntaxKind.StringLiteral
+        // SyntaxKind.RegularExpressionLiteral
+        // SyntaxKind.NoSubstitutionTemplateLiteral
+        // SyntaxKind.TemplateHead
+        // SyntaxKind.TemplateMiddle
+        // SyntaxKind.TemplateTail
+        function emitLiteral(node) {
+            var text = getLiteralTextOfNode(node);
+            if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
+                && (node.kind === 9 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
+                writer.writeLiteral(text);
+            }
+            else {
+                write(text);
+            }
+        }
+        //
+        // Identifiers
+        //
+        function emitIdentifier(node) {
+            write(getTextOfNode(node, /*includeTrivia*/ false));
+            emitTypeArguments(node, node.typeArguments);
+        }
+        //
+        // Names
+        //
+        function emitQualifiedName(node) {
+            emitEntityName(node.left);
+            write(".");
+            emit(node.right);
+        }
+        function emitEntityName(node) {
+            if (node.kind === 71 /* Identifier */) {
+                emitExpression(node);
+            }
+            else {
+                emit(node);
+            }
+        }
+        function emitComputedPropertyName(node) {
+            write("[");
+            emitExpression(node.expression);
+            write("]");
+        }
+        //
+        // Signature elements
+        //
+        function emitTypeParameter(node) {
+            emit(node.name);
+            emitWithPrefix(" extends ", node.constraint);
+            emitWithPrefix(" = ", node.default);
+        }
+        function emitParameter(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emitIfPresent(node.dotDotDotToken);
+            if (node.name) {
+                emit(node.name);
+            }
+            emitIfPresent(node.questionToken);
+            if (node.parent && node.parent.kind === 273 /* JSDocFunctionType */ && !node.name) {
+                emit(node.type);
+            }
+            else {
+                emitWithPrefix(": ", node.type);
+            }
+            emitExpressionWithPrefix(" = ", node.initializer);
+        }
+        function emitDecorator(decorator) {
+            write("@");
+            emitExpression(decorator.expression);
+        }
+        //
+        // Type members
+        //
+        function emitPropertySignature(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emit(node.name);
+            emitIfPresent(node.questionToken);
+            emitWithPrefix(": ", node.type);
+            write(";");
+        }
+        function emitPropertyDeclaration(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emit(node.name);
+            emitIfPresent(node.questionToken);
+            emitWithPrefix(": ", node.type);
+            emitExpressionWithPrefix(" = ", node.initializer);
+            write(";");
+        }
+        function emitMethodSignature(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emit(node.name);
+            emitIfPresent(node.questionToken);
+            emitTypeParameters(node, node.typeParameters);
+            emitParameters(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+            write(";");
+        }
+        function emitMethodDeclaration(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emitIfPresent(node.asteriskToken);
+            emit(node.name);
+            emitIfPresent(node.questionToken);
+            emitSignatureAndBody(node, emitSignatureHead);
+        }
+        function emitConstructor(node) {
+            emitModifiers(node, node.modifiers);
+            write("constructor");
+            emitSignatureAndBody(node, emitSignatureHead);
+        }
+        function emitAccessorDeclaration(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write(node.kind === 153 /* GetAccessor */ ? "get " : "set ");
+            emit(node.name);
+            emitSignatureAndBody(node, emitSignatureHead);
+        }
+        function emitCallSignature(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emitTypeParameters(node, node.typeParameters);
+            emitParameters(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+            write(";");
+        }
+        function emitConstructSignature(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write("new ");
+            emitTypeParameters(node, node.typeParameters);
+            emitParameters(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+            write(";");
+        }
+        function emitIndexSignature(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emitParametersForIndexSignature(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+            write(";");
+        }
+        function emitSemicolonClassElement() {
+            write(";");
+        }
+        //
+        // Types
+        //
+        function emitTypePredicate(node) {
+            emit(node.parameterName);
+            write(" is ");
+            emit(node.type);
+        }
+        function emitTypeReference(node) {
+            emit(node.typeName);
+            emitTypeArguments(node, node.typeArguments);
+        }
+        function emitFunctionType(node) {
+            emitTypeParameters(node, node.typeParameters);
+            emitParametersForArrow(node, node.parameters);
+            write(" => ");
+            emit(node.type);
+        }
+        function emitJSDocFunctionType(node) {
+            write("function");
+            emitParameters(node, node.parameters);
+            write(":");
+            emit(node.type);
+        }
+        function emitJSDocNullableType(node) {
+            write("?");
+            emit(node.type);
+        }
+        function emitJSDocNonNullableType(node) {
+            write("!");
+            emit(node.type);
+        }
+        function emitJSDocOptionalType(node) {
+            emit(node.type);
+            write("=");
+        }
+        function emitConstructorType(node) {
+            write("new ");
+            emitTypeParameters(node, node.typeParameters);
+            emitParameters(node, node.parameters);
+            write(" => ");
+            emit(node.type);
+        }
+        function emitTypeQuery(node) {
+            write("typeof ");
+            emit(node.exprName);
+        }
+        function emitTypeLiteral(node) {
+            write("{");
+            var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */;
+            emitList(node, node.members, flags | 262144 /* NoSpaceIfEmpty */);
+            write("}");
+        }
+        function emitArrayType(node) {
+            emit(node.elementType);
+            write("[]");
+        }
+        function emitJSDocVariadicType(node) {
+            write("...");
+            emit(node.type);
+        }
+        function emitTupleType(node) {
+            write("[");
+            emitList(node, node.elementTypes, 336 /* TupleTypeElements */);
+            write("]");
+        }
+        function emitUnionType(node) {
+            emitList(node, node.types, 260 /* UnionTypeConstituents */);
+        }
+        function emitIntersectionType(node) {
+            emitList(node, node.types, 264 /* IntersectionTypeConstituents */);
+        }
+        function emitParenthesizedType(node) {
+            write("(");
+            emit(node.type);
+            write(")");
+        }
+        function emitThisType() {
+            write("this");
+        }
+        function emitTypeOperator(node) {
+            writeTokenText(node.operator);
+            write(" ");
+            emit(node.type);
+        }
+        function emitIndexedAccessType(node) {
+            emit(node.objectType);
+            write("[");
+            emit(node.indexType);
+            write("]");
+        }
+        function emitMappedType(node) {
+            var emitFlags = ts.getEmitFlags(node);
+            write("{");
+            if (emitFlags & 1 /* SingleLine */) {
+                write(" ");
+            }
+            else {
+                writeLine();
+                increaseIndent();
+            }
+            if (node.readonlyToken) {
+                emit(node.readonlyToken);
+                write(" ");
+            }
+            write("[");
+            pipelineEmitWithNotification(3 /* MappedTypeParameter */, node.typeParameter);
+            write("]");
+            emitIfPresent(node.questionToken);
+            write(": ");
+            emit(node.type);
+            write(";");
+            if (emitFlags & 1 /* SingleLine */) {
+                write(" ");
+            }
+            else {
+                writeLine();
+                decreaseIndent();
+            }
+            write("}");
+        }
+        function emitLiteralType(node) {
+            emitExpression(node.literal);
+        }
+        //
+        // Binding patterns
+        //
+        function emitObjectBindingPattern(node) {
+            var elements = node.elements;
+            if (elements.length === 0) {
+                write("{}");
+            }
+            else {
+                write("{");
+                emitList(node, elements, 432 /* ObjectBindingPatternElements */);
+                write("}");
+            }
+        }
+        function emitArrayBindingPattern(node) {
+            var elements = node.elements;
+            if (elements.length === 0) {
+                write("[]");
+            }
+            else {
+                write("[");
+                emitList(node, node.elements, 304 /* ArrayBindingPatternElements */);
+                write("]");
+            }
+        }
+        function emitBindingElement(node) {
+            emitWithSuffix(node.propertyName, ": ");
+            emitIfPresent(node.dotDotDotToken);
+            emit(node.name);
+            emitExpressionWithPrefix(" = ", node.initializer);
+        }
+        //
+        // Expressions
+        //
+        function emitArrayLiteralExpression(node) {
+            var elements = node.elements;
+            var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */;
+            emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine);
+        }
+        function emitObjectLiteralExpression(node) {
+            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
+            if (indentedFlag) {
+                increaseIndent();
+            }
+            var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */;
+            var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */;
+            emitList(node, node.properties, 263122 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
+            if (indentedFlag) {
+                decreaseIndent();
+            }
+        }
+        function emitPropertyAccessExpression(node) {
+            var indentBeforeDot = false;
+            var indentAfterDot = false;
+            if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) {
+                var dotRangeStart = node.expression.end;
+                var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1;
+                var dotToken = ts.createToken(23 /* DotToken */);
+                dotToken.pos = dotRangeStart;
+                dotToken.end = dotRangeEnd;
+                indentBeforeDot = needsIndentation(node, node.expression, dotToken);
+                indentAfterDot = needsIndentation(node, dotToken, node.name);
+            }
+            emitExpression(node.expression);
+            increaseIndentIf(indentBeforeDot);
+            var shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression);
+            write(shouldEmitDotDot ? ".." : ".");
+            increaseIndentIf(indentAfterDot);
+            emit(node.name);
+            decreaseIndentIf(indentBeforeDot, indentAfterDot);
+        }
+        // 1..toString is a valid property access, emit a dot after the literal
+        // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
+        function needsDotDotForPropertyAccess(expression) {
+            expression = ts.skipPartiallyEmittedExpressions(expression);
+            if (ts.isNumericLiteral(expression)) {
+                // check if numeric literal is a decimal literal that was originally written with a dot
+                var text = getLiteralTextOfNode(expression);
+                return !expression.numericLiteralFlags
+                    && !ts.stringContains(text, ts.tokenToString(23 /* DotToken */));
+            }
+            else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) {
+                // check if constant enum value is integer
+                var constantValue = ts.getConstantValue(expression);
+                // isFinite handles cases when constantValue is undefined
+                return typeof constantValue === "number" && isFinite(constantValue)
+                    && Math.floor(constantValue) === constantValue
+                    && printerOptions.removeComments;
+            }
+        }
+        function emitElementAccessExpression(node) {
+            emitExpression(node.expression);
+            write("[");
+            emitExpression(node.argumentExpression);
+            write("]");
+        }
+        function emitCallExpression(node) {
+            emitExpression(node.expression);
+            emitTypeArguments(node, node.typeArguments);
+            emitExpressionList(node, node.arguments, 1296 /* CallExpressionArguments */);
+        }
+        function emitNewExpression(node) {
+            write("new ");
+            emitExpression(node.expression);
+            emitTypeArguments(node, node.typeArguments);
+            emitExpressionList(node, node.arguments, 9488 /* NewExpressionArguments */);
+        }
+        function emitTaggedTemplateExpression(node) {
+            emitExpression(node.tag);
+            write(" ");
+            emitExpression(node.template);
+        }
+        function emitTypeAssertionExpression(node) {
+            write("<");
+            emit(node.type);
+            write(">");
+            emitExpression(node.expression);
+        }
+        function emitParenthesizedExpression(node) {
+            write("(");
+            emitExpression(node.expression);
+            write(")");
+        }
+        function emitFunctionExpression(node) {
+            emitFunctionDeclarationOrExpression(node);
+        }
+        function emitArrowFunction(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            emitSignatureAndBody(node, emitArrowFunctionHead);
+        }
+        function emitArrowFunctionHead(node) {
+            emitTypeParameters(node, node.typeParameters);
+            emitParametersForArrow(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+            write(" ");
+            emit(node.equalsGreaterThanToken);
+        }
+        function emitDeleteExpression(node) {
+            write("delete ");
+            emitExpression(node.expression);
+        }
+        function emitTypeOfExpression(node) {
+            write("typeof ");
+            emitExpression(node.expression);
+        }
+        function emitVoidExpression(node) {
+            write("void ");
+            emitExpression(node.expression);
+        }
+        function emitAwaitExpression(node) {
+            write("await ");
+            emitExpression(node.expression);
+        }
+        function emitPrefixUnaryExpression(node) {
+            writeTokenText(node.operator);
+            if (shouldEmitWhitespaceBeforeOperand(node)) {
+                write(" ");
+            }
+            emitExpression(node.operand);
+        }
+        function shouldEmitWhitespaceBeforeOperand(node) {
+            // In some cases, we need to emit a space between the operator and the operand. One obvious case
+            // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
+            // and minus expressions in certain cases. Specifically, consider the following two cases (parens
+            // are just for clarity of exposition, and not part of the source code):
+            //
+            //  (+(+1))
+            //  (+(++1))
+            //
+            // We need to emit a space in both cases. In the first case, the absence of a space will make
+            // the resulting expression a prefix increment operation. And in the second, it will make the resulting
+            // expression a prefix increment whose operand is a plus expression - (++(+x))
+            // The same is true of minus of course.
+            var operand = node.operand;
+            return operand.kind === 192 /* PrefixUnaryExpression */
+                && ((node.operator === 37 /* PlusToken */ && (operand.operator === 37 /* PlusToken */ || operand.operator === 43 /* PlusPlusToken */))
+                    || (node.operator === 38 /* MinusToken */ && (operand.operator === 38 /* MinusToken */ || operand.operator === 44 /* MinusMinusToken */)));
+        }
+        function emitPostfixUnaryExpression(node) {
+            emitExpression(node.operand);
+            writeTokenText(node.operator);
+        }
+        function emitBinaryExpression(node) {
+            var isCommaOperator = node.operatorToken.kind !== 26 /* CommaToken */;
+            var indentBeforeOperator = needsIndentation(node, node.left, node.operatorToken);
+            var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right);
+            emitExpression(node.left);
+            increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined);
+            emitLeadingCommentsOfPosition(node.operatorToken.pos);
+            writeTokenNode(node.operatorToken);
+            emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
+            increaseIndentIf(indentAfterOperator, " ");
+            emitExpression(node.right);
+            decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
+        }
+        function emitConditionalExpression(node) {
+            var indentBeforeQuestion = needsIndentation(node, node.condition, node.questionToken);
+            var indentAfterQuestion = needsIndentation(node, node.questionToken, node.whenTrue);
+            var indentBeforeColon = needsIndentation(node, node.whenTrue, node.colonToken);
+            var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse);
+            emitExpression(node.condition);
+            increaseIndentIf(indentBeforeQuestion, " ");
+            emit(node.questionToken);
+            increaseIndentIf(indentAfterQuestion, " ");
+            emitExpression(node.whenTrue);
+            decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion);
+            increaseIndentIf(indentBeforeColon, " ");
+            emit(node.colonToken);
+            increaseIndentIf(indentAfterColon, " ");
+            emitExpression(node.whenFalse);
+            decreaseIndentIf(indentBeforeColon, indentAfterColon);
+        }
+        function emitTemplateExpression(node) {
+            emit(node.head);
+            emitList(node, node.templateSpans, 131072 /* TemplateExpressionSpans */);
+        }
+        function emitYieldExpression(node) {
+            write("yield");
+            emit(node.asteriskToken);
+            emitExpressionWithPrefix(" ", node.expression);
+        }
+        function emitSpreadExpression(node) {
+            write("...");
+            emitExpression(node.expression);
+        }
+        function emitClassExpression(node) {
+            emitClassDeclarationOrExpression(node);
+        }
+        function emitExpressionWithTypeArguments(node) {
+            emitExpression(node.expression);
+            emitTypeArguments(node, node.typeArguments);
+        }
+        function emitAsExpression(node) {
+            emitExpression(node.expression);
+            if (node.type) {
+                write(" as ");
+                emit(node.type);
+            }
+        }
+        function emitNonNullExpression(node) {
+            emitExpression(node.expression);
+            write("!");
+        }
+        function emitMetaProperty(node) {
+            writeToken(node.keywordToken, node.pos);
+            write(".");
+            emit(node.name);
+        }
+        //
+        // Misc
+        //
+        function emitTemplateSpan(node) {
+            emitExpression(node.expression);
+            emit(node.literal);
+        }
+        //
+        // Statements
+        //
+        function emitBlock(node) {
+            writeToken(17 /* OpenBraceToken */, node.pos, /*contextNode*/ node);
+            emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
+            // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted
+            increaseIndent();
+            emitLeadingCommentsOfPosition(node.statements.end);
+            decreaseIndent();
+            writeToken(18 /* CloseBraceToken */, node.statements.end, /*contextNode*/ node);
+        }
+        function emitBlockStatements(node, forceSingleLine) {
+            var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 384 /* SingleLineBlockStatements */ : 65 /* MultiLineBlockStatements */;
+            emitList(node, node.statements, format);
+        }
+        function emitVariableStatement(node) {
+            emitModifiers(node, node.modifiers);
+            emit(node.declarationList);
+            write(";");
+        }
+        function emitEmptyStatement() {
+            write(";");
+        }
+        function emitExpressionStatement(node) {
+            emitExpression(node.expression);
+            write(";");
+        }
+        function emitIfStatement(node) {
+            var openParenPos = writeToken(90 /* IfKeyword */, node.pos, node);
+            write(" ");
+            writeToken(19 /* OpenParenToken */, openParenPos, node);
+            emitExpression(node.expression);
+            writeToken(20 /* CloseParenToken */, node.expression.end, node);
+            emitEmbeddedStatement(node, node.thenStatement);
+            if (node.elseStatement) {
+                writeLineOrSpace(node);
+                writeToken(82 /* ElseKeyword */, node.thenStatement.end, node);
+                if (node.elseStatement.kind === 211 /* IfStatement */) {
+                    write(" ");
+                    emit(node.elseStatement);
+                }
+                else {
+                    emitEmbeddedStatement(node, node.elseStatement);
+                }
+            }
+        }
+        function emitDoStatement(node) {
+            write("do");
+            emitEmbeddedStatement(node, node.statement);
+            if (ts.isBlock(node.statement)) {
+                write(" ");
+            }
+            else {
+                writeLineOrSpace(node);
+            }
+            write("while (");
+            emitExpression(node.expression);
+            write(");");
+        }
+        function emitWhileStatement(node) {
+            write("while (");
+            emitExpression(node.expression);
+            write(")");
+            emitEmbeddedStatement(node, node.statement);
+        }
+        function emitForStatement(node) {
+            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
+            write(" ");
+            writeToken(19 /* OpenParenToken */, openParenPos, /*contextNode*/ node);
+            emitForBinding(node.initializer);
+            write(";");
+            emitExpressionWithPrefix(" ", node.condition);
+            write(";");
+            emitExpressionWithPrefix(" ", node.incrementor);
+            write(")");
+            emitEmbeddedStatement(node, node.statement);
+        }
+        function emitForInStatement(node) {
+            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
+            write(" ");
+            writeToken(19 /* OpenParenToken */, openParenPos);
+            emitForBinding(node.initializer);
+            write(" in ");
+            emitExpression(node.expression);
+            writeToken(20 /* CloseParenToken */, node.expression.end);
+            emitEmbeddedStatement(node, node.statement);
+        }
+        function emitForOfStatement(node) {
+            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
+            write(" ");
+            emitWithSuffix(node.awaitModifier, " ");
+            writeToken(19 /* OpenParenToken */, openParenPos);
+            emitForBinding(node.initializer);
+            write(" of ");
+            emitExpression(node.expression);
+            writeToken(20 /* CloseParenToken */, node.expression.end);
+            emitEmbeddedStatement(node, node.statement);
+        }
+        function emitForBinding(node) {
+            if (node !== undefined) {
+                if (node.kind === 227 /* VariableDeclarationList */) {
+                    emit(node);
+                }
+                else {
+                    emitExpression(node);
+                }
+            }
+        }
+        function emitContinueStatement(node) {
+            writeToken(77 /* ContinueKeyword */, node.pos);
+            emitWithPrefix(" ", node.label);
+            write(";");
+        }
+        function emitBreakStatement(node) {
+            writeToken(72 /* BreakKeyword */, node.pos);
+            emitWithPrefix(" ", node.label);
+            write(";");
+        }
+        function emitTokenWithComment(token, pos, contextNode) {
+            var node = contextNode && ts.getParseTreeNode(contextNode);
+            if (node && node.kind === contextNode.kind) {
+                pos = ts.skipTrivia(currentSourceFile.text, pos);
+            }
+            pos = writeToken(token, pos, /*contextNode*/ contextNode);
+            if (node && node.kind === contextNode.kind) {
+                emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
+            }
+            return pos;
+        }
+        function emitReturnStatement(node) {
+            emitTokenWithComment(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node);
+            emitExpressionWithPrefix(" ", node.expression);
+            write(";");
+        }
+        function emitWithStatement(node) {
+            write("with (");
+            emitExpression(node.expression);
+            write(")");
+            emitEmbeddedStatement(node, node.statement);
+        }
+        function emitSwitchStatement(node) {
+            var openParenPos = writeToken(98 /* SwitchKeyword */, node.pos);
+            write(" ");
+            writeToken(19 /* OpenParenToken */, openParenPos);
+            emitExpression(node.expression);
+            writeToken(20 /* CloseParenToken */, node.expression.end);
+            write(" ");
+            emit(node.caseBlock);
+        }
+        function emitLabeledStatement(node) {
+            emit(node.label);
+            write(": ");
+            emit(node.statement);
+        }
+        function emitThrowStatement(node) {
+            write("throw");
+            emitExpressionWithPrefix(" ", node.expression);
+            write(";");
+        }
+        function emitTryStatement(node) {
+            write("try ");
+            emit(node.tryBlock);
+            if (node.catchClause) {
+                writeLineOrSpace(node);
+                emit(node.catchClause);
+            }
+            if (node.finallyBlock) {
+                writeLineOrSpace(node);
+                write("finally ");
+                emit(node.finallyBlock);
+            }
+        }
+        function emitDebuggerStatement(node) {
+            writeToken(78 /* DebuggerKeyword */, node.pos);
+            write(";");
+        }
+        //
+        // Declarations
+        //
+        function emitVariableDeclaration(node) {
+            emit(node.name);
+            emitWithPrefix(": ", node.type);
+            emitExpressionWithPrefix(" = ", node.initializer);
+        }
+        function emitVariableDeclarationList(node) {
+            write(ts.isLet(node) ? "let " : ts.isConst(node) ? "const " : "var ");
+            emitList(node, node.declarations, 272 /* VariableDeclarationList */);
+        }
+        function emitFunctionDeclaration(node) {
+            emitFunctionDeclarationOrExpression(node);
+        }
+        function emitFunctionDeclarationOrExpression(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write("function");
+            emitIfPresent(node.asteriskToken);
+            write(" ");
+            emitIdentifierName(node.name);
+            emitSignatureAndBody(node, emitSignatureHead);
+        }
+        function emitBlockCallback(_hint, body) {
+            emitBlockFunctionBody(body);
+        }
+        function emitSignatureAndBody(node, emitSignatureHead) {
+            var body = node.body;
+            if (body) {
+                if (ts.isBlock(body)) {
+                    var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
+                    if (indentedFlag) {
+                        increaseIndent();
+                    }
+                    if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
+                        emitSignatureHead(node);
+                        if (onEmitNode) {
+                            onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
+                        }
+                        else {
+                            emitBlockFunctionBody(body);
+                        }
+                    }
+                    else {
+                        pushNameGenerationScope();
+                        emitSignatureHead(node);
+                        if (onEmitNode) {
+                            onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
+                        }
+                        else {
+                            emitBlockFunctionBody(body);
+                        }
+                        popNameGenerationScope();
+                    }
+                    if (indentedFlag) {
+                        decreaseIndent();
+                    }
+                }
+                else {
+                    emitSignatureHead(node);
+                    write(" ");
+                    emitExpression(body);
+                }
+            }
+            else {
+                emitSignatureHead(node);
+                write(";");
+            }
+        }
+        function emitSignatureHead(node) {
+            emitTypeParameters(node, node.typeParameters);
+            emitParameters(node, node.parameters);
+            emitWithPrefix(": ", node.type);
+        }
+        function shouldEmitBlockFunctionBodyOnSingleLine(body) {
+            // We must emit a function body as a single-line body in the following case:
+            // * The body has NodeEmitFlags.SingleLine specified.
+            // We must emit a function body as a multi-line body in the following cases:
+            // * The body is explicitly marked as multi-line.
+            // * A non-synthesized body's start and end position are on different lines.
+            // * Any statement in the body starts on a new line.
+            if (ts.getEmitFlags(body) & 1 /* SingleLine */) {
+                return true;
+            }
+            if (body.multiLine) {
+                return false;
+            }
+            if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) {
+                return false;
+            }
+            if (shouldWriteLeadingLineTerminator(body, body.statements, 2 /* PreserveLines */)
+                || shouldWriteClosingLineTerminator(body, body.statements, 2 /* PreserveLines */)) {
+                return false;
+            }
+            var previousStatement;
+            for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
+                var statement = _b[_a];
+                if (shouldWriteSeparatingLineTerminator(previousStatement, statement, 2 /* PreserveLines */)) {
+                    return false;
+                }
+                previousStatement = statement;
+            }
+            return true;
+        }
+        function emitBlockFunctionBody(body) {
+            write(" {");
+            increaseIndent();
+            var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
+                ? emitBlockFunctionBodyOnSingleLine
+                : emitBlockFunctionBodyWorker;
+            if (emitBodyWithDetachedComments) {
+                emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
+            }
+            else {
+                emitBlockFunctionBody(body);
+            }
+            decreaseIndent();
+            writeToken(18 /* CloseBraceToken */, body.statements.end, body);
+        }
+        function emitBlockFunctionBodyOnSingleLine(body) {
+            emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
+        }
+        function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
+            // Emit all the prologue directives (like "use strict").
+            var statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true);
+            var pos = writer.getTextPos();
+            emitHelpersIndirect(body);
+            if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
+                decreaseIndent();
+                emitList(body, body.statements, 384 /* SingleLineFunctionBodyStatements */);
+                increaseIndent();
+            }
+            else {
+                emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset);
+            }
+        }
+        function emitClassDeclaration(node) {
+            emitClassDeclarationOrExpression(node);
+        }
+        function emitClassDeclarationOrExpression(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write("class");
+            emitNodeWithPrefix(" ", node.name, emitIdentifierName);
+            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
+            if (indentedFlag) {
+                increaseIndent();
+            }
+            emitTypeParameters(node, node.typeParameters);
+            emitList(node, node.heritageClauses, 256 /* ClassHeritageClauses */);
+            pushNameGenerationScope();
+            write(" {");
+            emitList(node, node.members, 65 /* ClassMembers */);
+            write("}");
+            popNameGenerationScope();
+            if (indentedFlag) {
+                decreaseIndent();
+            }
+        }
+        function emitInterfaceDeclaration(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write("interface ");
+            emit(node.name);
+            emitTypeParameters(node, node.typeParameters);
+            emitList(node, node.heritageClauses, 256 /* HeritageClauses */);
+            write(" {");
+            emitList(node, node.members, 65 /* InterfaceMembers */);
+            write("}");
+        }
+        function emitTypeAliasDeclaration(node) {
+            emitDecorators(node, node.decorators);
+            emitModifiers(node, node.modifiers);
+            write("type ");
+            emit(node.name);
+            emitTypeParameters(node, node.typeParameters);
+            write(" = ");
+            emit(node.type);
+            write(";");
+        }
+        function emitEnumDeclaration(node) {
+            emitModifiers(node, node.modifiers);
+            write("enum ");
+            emit(node.name);
+            pushNameGenerationScope();
+            write(" {");
+            emitList(node, node.members, 81 /* EnumMembers */);
+            write("}");
+            popNameGenerationScope();
+        }
+        function emitModuleDeclaration(node) {
+            emitModifiers(node, node.modifiers);
+            if (~node.flags & 512 /* GlobalAugmentation */) {
+                write(node.flags & 16 /* Namespace */ ? "namespace " : "module ");
+            }
+            emit(node.name);
+            var body = node.body;
+            while (body.kind === 233 /* ModuleDeclaration */) {
+                write(".");
+                emit(body.name);
+                body = body.body;
+            }
+            write(" ");
+            emit(body);
+        }
+        function emitModuleBlock(node) {
+            pushNameGenerationScope();
+            write("{");
+            emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
+            write("}");
+            popNameGenerationScope();
+        }
+        function emitCaseBlock(node) {
+            writeToken(17 /* OpenBraceToken */, node.pos);
+            emitList(node, node.clauses, 65 /* CaseBlockClauses */);
+            writeToken(18 /* CloseBraceToken */, node.clauses.end);
+        }
+        function emitImportEqualsDeclaration(node) {
+            emitModifiers(node, node.modifiers);
+            write("import ");
+            emit(node.name);
+            write(" = ");
+            emitModuleReference(node.moduleReference);
+            write(";");
+        }
+        function emitModuleReference(node) {
+            if (node.kind === 71 /* Identifier */) {
+                emitExpression(node);
+            }
+            else {
+                emit(node);
+            }
+        }
+        function emitImportDeclaration(node) {
+            emitModifiers(node, node.modifiers);
+            write("import ");
+            if (node.importClause) {
+                emit(node.importClause);
+                write(" from ");
+            }
+            emitExpression(node.moduleSpecifier);
+            write(";");
+        }
+        function emitImportClause(node) {
+            emit(node.name);
+            if (node.name && node.namedBindings) {
+                write(", ");
+            }
+            emit(node.namedBindings);
+        }
+        function emitNamespaceImport(node) {
+            write("* as ");
+            emit(node.name);
+        }
+        function emitNamedImports(node) {
+            emitNamedImportsOrExports(node);
+        }
+        function emitImportSpecifier(node) {
+            emitImportOrExportSpecifier(node);
+        }
+        function emitExportAssignment(node) {
+            write(node.isExportEquals ? "export = " : "export default ");
+            emitExpression(node.expression);
+            write(";");
+        }
+        function emitExportDeclaration(node) {
+            write("export ");
+            if (node.exportClause) {
+                emit(node.exportClause);
+            }
+            else {
+                write("*");
+            }
+            if (node.moduleSpecifier) {
+                write(" from ");
+                emitExpression(node.moduleSpecifier);
+            }
+            write(";");
+        }
+        function emitNamespaceExportDeclaration(node) {
+            write("export as namespace ");
+            emit(node.name);
+            write(";");
+        }
+        function emitNamedExports(node) {
+            emitNamedImportsOrExports(node);
+        }
+        function emitExportSpecifier(node) {
+            emitImportOrExportSpecifier(node);
+        }
+        function emitNamedImportsOrExports(node) {
+            write("{");
+            emitList(node, node.elements, 432 /* NamedImportsOrExportsElements */);
+            write("}");
+        }
+        function emitImportOrExportSpecifier(node) {
+            if (node.propertyName) {
+                emit(node.propertyName);
+                write(" as ");
+            }
+            emit(node.name);
+        }
+        //
+        // Module references
+        //
+        function emitExternalModuleReference(node) {
+            write("require(");
+            emitExpression(node.expression);
+            write(")");
+        }
+        //
+        // JSX
+        //
+        function emitJsxElement(node) {
+            emit(node.openingElement);
+            emitList(node, node.children, 131072 /* JsxElementChildren */);
+            emit(node.closingElement);
+        }
+        function emitJsxSelfClosingElement(node) {
+            write("<");
+            emitJsxTagName(node.tagName);
+            write(" ");
+            // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
+            if (node.attributes.properties && node.attributes.properties.length > 0) {
+                emit(node.attributes);
+            }
+            write("/>");
+        }
+        function emitJsxOpeningElement(node) {
+            write("<");
+            emitJsxTagName(node.tagName);
+            writeIfAny(node.attributes.properties, " ");
+            // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
+            if (node.attributes.properties && node.attributes.properties.length > 0) {
+                emit(node.attributes);
+            }
+            write(">");
+        }
+        function emitJsxText(node) {
+            writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
+        }
+        function emitJsxClosingElement(node) {
+            write("</");
+            emitJsxTagName(node.tagName);
+            write(">");
+        }
+        function emitJsxAttributes(node) {
+            emitList(node, node.properties, 131328 /* JsxElementAttributes */);
+        }
+        function emitJsxAttribute(node) {
+            emit(node.name);
+            emitWithPrefix("=", node.initializer);
+        }
+        function emitJsxSpreadAttribute(node) {
+            write("{...");
+            emitExpression(node.expression);
+            write("}");
+        }
+        function emitJsxExpression(node) {
+            if (node.expression) {
+                write("{");
+                emitIfPresent(node.dotDotDotToken);
+                emitExpression(node.expression);
+                write("}");
+            }
+        }
+        function emitJsxTagName(node) {
+            if (node.kind === 71 /* Identifier */) {
+                emitExpression(node);
+            }
+            else {
+                emit(node);
+            }
+        }
+        //
+        // Clauses
+        //
+        function emitCaseClause(node) {
+            write("case ");
+            emitExpression(node.expression);
+            write(":");
+            emitCaseOrDefaultClauseStatements(node, node.statements);
+        }
+        function emitDefaultClause(node) {
+            write("default:");
+            emitCaseOrDefaultClauseStatements(node, node.statements);
+        }
+        function emitCaseOrDefaultClauseStatements(parentNode, statements) {
+            var emitAsSingleStatement = statements.length === 1 &&
+                (
+                // treat synthesized nodes as located on the same line for emit purposes
+                ts.nodeIsSynthesized(parentNode) ||
+                    ts.nodeIsSynthesized(statements[0]) ||
+                    ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
+            // e.g:
+            //      case 0: // Zero
+            //      case 1: // One
+            //      case 2: // two
+            //          return "hi";
+            // If there is no statements, emitNodeWithComments of the parentNode which is caseClause will take care of trailing comment.
+            // So in example above, comment "// Zero" and "// One" will be emit in emitTrailingComments in emitNodeWithComments.
+            // However, for "case 2", because parentNode which is caseClause has an "end" property to be end of the statements (in this case return statement)
+            // comment "// two" will not be emitted in emitNodeWithComments.
+            // Therefore, we have to do the check here to emit such comment.
+            if (statements.length > 0) {
+                // We use emitTrailingCommentsOfPosition instead of emitLeadingCommentsOfPosition because leading comments is defined as comments before the node after newline character separating it from previous line
+                // Note: we can't use parentNode.end as such position includes statements.
+                emitTrailingCommentsOfPosition(statements.pos);
+            }
+            var format = 81985 /* CaseOrDefaultClauseStatements */;
+            if (emitAsSingleStatement) {
+                write(" ");
+                format &= ~(1 /* MultiLine */ | 64 /* Indented */);
+            }
+            emitList(parentNode, statements, format);
+        }
+        function emitHeritageClause(node) {
+            write(" ");
+            writeTokenText(node.token);
+            write(" ");
+            emitList(node, node.types, 272 /* HeritageClauseTypes */);
+        }
+        function emitCatchClause(node) {
+            var openParenPos = writeToken(74 /* CatchKeyword */, node.pos);
+            write(" ");
+            if (node.variableDeclaration) {
+                writeToken(19 /* OpenParenToken */, openParenPos);
+                emit(node.variableDeclaration);
+                writeToken(20 /* CloseParenToken */, node.variableDeclaration.end);
+                write(" ");
+            }
+            emit(node.block);
+        }
+        //
+        // Property assignments
+        //
+        function emitPropertyAssignment(node) {
+            emit(node.name);
+            write(": ");
+            // This is to ensure that we emit comment in the following case:
+            //      For example:
+            //          obj = {
+            //              id: /*comment1*/ ()=>void
+            //          }
+            // "comment1" is not considered to be leading comment for node.initializer
+            // but rather a trailing comment on the previous node.
+            var initializer = node.initializer;
+            if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) {
+                var commentRange = ts.getCommentRange(initializer);
+                emitTrailingCommentsOfPosition(commentRange.pos);
+            }
+            emitExpression(initializer);
+        }
+        function emitShorthandPropertyAssignment(node) {
+            emit(node.name);
+            if (node.objectAssignmentInitializer) {
+                write(" = ");
+                emitExpression(node.objectAssignmentInitializer);
+            }
+        }
+        function emitSpreadAssignment(node) {
+            if (node.expression) {
+                write("...");
+                emitExpression(node.expression);
+            }
+        }
+        //
+        // Enum
+        //
+        function emitEnumMember(node) {
+            emit(node.name);
+            emitExpressionWithPrefix(" = ", node.initializer);
+        }
+        //
+        // Top-level nodes
+        //
+        function emitSourceFile(node) {
+            writeLine();
+            var statements = node.statements;
+            if (emitBodyWithDetachedComments) {
+                // Emit detached comment if there are no prologue directives or if the first node is synthesized.
+                // The synthesized node will have no leading comment so some comments may be missed.
+                var shouldEmitDetachedComment = statements.length === 0 ||
+                    !ts.isPrologueDirective(statements[0]) ||
+                    ts.nodeIsSynthesized(statements[0]);
+                if (shouldEmitDetachedComment) {
+                    emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
+                    return;
+                }
+            }
+            emitSourceFileWorker(node);
+        }
+        function emitSourceFileWorker(node) {
+            var statements = node.statements;
+            pushNameGenerationScope();
+            emitHelpersIndirect(node);
+            var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); });
+            emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index);
+            popNameGenerationScope();
+        }
+        // Transformation nodes
+        function emitPartiallyEmittedExpression(node) {
+            emitExpression(node.expression);
+        }
+        function emitCommaList(node) {
+            emitExpressionList(node, node.elements, 272 /* CommaListElements */);
+        }
+        /**
+         * Emits any prologue directives at the start of a Statement list, returning the
+         * number of prologue directives written to the output.
+         */
+        function emitPrologueDirectives(statements, startWithNewLine, seenPrologueDirectives) {
+            for (var i = 0; i < statements.length; i++) {
+                var statement = statements[i];
+                if (ts.isPrologueDirective(statement)) {
+                    var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
+                    if (shouldEmitPrologueDirective) {
+                        if (startWithNewLine || i > 0) {
+                            writeLine();
+                        }
+                        emit(statement);
+                        if (seenPrologueDirectives) {
+                            seenPrologueDirectives.set(statement.expression.text, true);
+                        }
+                    }
+                }
+                else {
+                    // return index of the first non prologue directive
+                    return i;
+                }
+            }
+            return statements.length;
+        }
+        function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
+            if (ts.isSourceFile(sourceFileOrBundle)) {
+                setSourceFile(sourceFileOrBundle);
+                emitPrologueDirectives(sourceFileOrBundle.statements);
+            }
+            else {
+                var seenPrologueDirectives = ts.createMap();
+                for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) {
+                    var sourceFile = _b[_a];
+                    setSourceFile(sourceFile);
+                    emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
+                }
+            }
+        }
+        function emitShebangIfNeeded(sourceFileOrBundle) {
+            if (ts.isSourceFile(sourceFileOrBundle)) {
+                var shebang = ts.getShebang(sourceFileOrBundle.text);
+                if (shebang) {
+                    write(shebang);
+                    writeLine();
+                    return true;
+                }
+            }
+            else {
+                for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) {
+                    var sourceFile = _b[_a];
+                    // Emit only the first encountered shebang
+                    if (emitShebangIfNeeded(sourceFile)) {
+                        break;
+                    }
+                }
+            }
+        }
+        //
+        // Helpers
+        //
+        function emitModifiers(node, modifiers) {
+            if (modifiers && modifiers.length) {
+                emitList(node, modifiers, 131328 /* Modifiers */);
+                write(" ");
+            }
+        }
+        function emitWithPrefix(prefix, node) {
+            emitNodeWithPrefix(prefix, node, emit);
+        }
+        function emitExpressionWithPrefix(prefix, node) {
+            emitNodeWithPrefix(prefix, node, emitExpression);
+        }
+        function emitNodeWithPrefix(prefix, node, emit) {
+            if (node) {
+                write(prefix);
+                emit(node);
+            }
+        }
+        function emitWithSuffix(node, suffix) {
+            if (node) {
+                emit(node);
+                write(suffix);
+            }
+        }
+        function emitEmbeddedStatement(parent, node) {
+            if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) {
+                write(" ");
+                emit(node);
+            }
+            else {
+                writeLine();
+                increaseIndent();
+                emit(node);
+                decreaseIndent();
+            }
+        }
+        function emitDecorators(parentNode, decorators) {
+            emitList(parentNode, decorators, 24577 /* Decorators */);
+        }
+        function emitTypeArguments(parentNode, typeArguments) {
+            emitList(parentNode, typeArguments, 26960 /* TypeArguments */);
+        }
+        function emitTypeParameters(parentNode, typeParameters) {
+            emitList(parentNode, typeParameters, 26960 /* TypeParameters */);
+        }
+        function emitParameters(parentNode, parameters) {
+            emitList(parentNode, parameters, 1360 /* Parameters */);
+        }
+        function canEmitSimpleArrowHead(parentNode, parameters) {
+            var parameter = ts.singleOrUndefined(parameters);
+            return parameter
+                && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
+                && !(ts.isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation
+                && !ts.some(parentNode.decorators) // parent may not have decorators
+                && !ts.some(parentNode.modifiers) // parent may not have modifiers
+                && !ts.some(parentNode.typeParameters) // parent may not have type parameters
+                && !ts.some(parameter.decorators) // parameter may not have decorators
+                && !ts.some(parameter.modifiers) // parameter may not have modifiers
+                && !parameter.dotDotDotToken // parameter may not be rest
+                && !parameter.questionToken // parameter may not be optional
+                && !parameter.type // parameter may not have a type annotation
+                && !parameter.initializer // parameter may not have an initializer
+                && ts.isIdentifier(parameter.name); // parameter name must be identifier
+        }
+        function emitParametersForArrow(parentNode, parameters) {
+            if (canEmitSimpleArrowHead(parentNode, parameters)) {
+                emitList(parentNode, parameters, 1360 /* Parameters */ & ~1024 /* Parenthesis */);
+            }
+            else {
+                emitParameters(parentNode, parameters);
+            }
+        }
+        function emitParametersForIndexSignature(parentNode, parameters) {
+            emitList(parentNode, parameters, 4432 /* IndexSignatureParameters */);
+        }
+        function emitList(parentNode, children, format, start, count) {
+            emitNodeList(emit, parentNode, children, format, start, count);
+        }
+        function emitExpressionList(parentNode, children, format, start, count) {
+            emitNodeList(emitExpression, parentNode, children, format, start, count);
+        }
+        function emitNodeList(emit, parentNode, children, format, start, count) {
+            if (start === void 0) { start = 0; }
+            if (count === void 0) { count = children ? children.length - start : 0; }
+            var isUndefined = children === undefined;
+            if (isUndefined && format & 8192 /* OptionalIfUndefined */) {
+                return;
+            }
+            var isEmpty = isUndefined || start >= children.length || count === 0;
+            if (isEmpty && format & 16384 /* OptionalIfEmpty */) {
+                if (onBeforeEmitNodeArray) {
+                    onBeforeEmitNodeArray(children);
+                }
+                if (onAfterEmitNodeArray) {
+                    onAfterEmitNodeArray(children);
+                }
+                return;
+            }
+            if (format & 7680 /* BracketsMask */) {
+                write(getOpeningBracket(format));
+            }
+            if (onBeforeEmitNodeArray) {
+                onBeforeEmitNodeArray(children);
+            }
+            if (isEmpty) {
+                // Write a line terminator if the parent node was multi-line
+                if (format & 1 /* MultiLine */) {
+                    writeLine();
+                }
+                else if (format & 128 /* SpaceBetweenBraces */ && !(format & 262144 /* NoSpaceIfEmpty */)) {
+                    write(" ");
+                }
+            }
+            else {
+                // Write the opening line terminator or leading whitespace.
+                var mayEmitInterveningComments = (format & 131072 /* NoInterveningComments */) === 0;
+                var shouldEmitInterveningComments = mayEmitInterveningComments;
+                if (shouldWriteLeadingLineTerminator(parentNode, children, format)) {
+                    writeLine();
+                    shouldEmitInterveningComments = false;
+                }
+                else if (format & 128 /* SpaceBetweenBraces */) {
+                    write(" ");
+                }
+                // Increase the indent, if requested.
+                if (format & 64 /* Indented */) {
+                    increaseIndent();
+                }
+                // Emit each child.
+                var previousSibling = void 0;
+                var shouldDecreaseIndentAfterEmit = void 0;
+                var delimiter = getDelimiter(format);
+                for (var i = 0; i < count; i++) {
+                    var child = children[start + i];
+                    // Write the delimiter if this is not the first node.
+                    if (previousSibling) {
+                        // i.e
+                        //      function commentedParameters(
+                        //          /* Parameter a */
+                        //          a
+                        //          /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
+                        //          ,
+                        if (delimiter && previousSibling.end !== parentNode.end) {
+                            emitLeadingCommentsOfPosition(previousSibling.end);
+                        }
+                        write(delimiter);
+                        // Write either a line terminator or whitespace to separate the elements.
+                        if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
+                            // If a synthesized node in a single-line list starts on a new
+                            // line, we should increase the indent.
+                            if ((format & (3 /* LinesMask */ | 64 /* Indented */)) === 0 /* SingleLine */) {
+                                increaseIndent();
+                                shouldDecreaseIndentAfterEmit = true;
+                            }
+                            writeLine();
+                            shouldEmitInterveningComments = false;
+                        }
+                        else if (previousSibling && format & 256 /* SpaceBetweenSiblings */) {
+                            write(" ");
+                        }
+                    }
+                    // Emit this child.
+                    if (shouldEmitInterveningComments) {
+                        if (emitTrailingCommentsOfPosition) {
+                            var commentRange = ts.getCommentRange(child);
+                            emitTrailingCommentsOfPosition(commentRange.pos);
+                        }
+                    }
+                    else {
+                        shouldEmitInterveningComments = mayEmitInterveningComments;
+                    }
+                    emit(child);
+                    if (shouldDecreaseIndentAfterEmit) {
+                        decreaseIndent();
+                        shouldDecreaseIndentAfterEmit = false;
+                    }
+                    previousSibling = child;
+                }
+                // Write a trailing comma, if requested.
+                var hasTrailingComma = (format & 32 /* AllowTrailingComma */) && children.hasTrailingComma;
+                if (format & 16 /* CommaDelimited */ && hasTrailingComma) {
+                    write(",");
+                }
+                // Emit any trailing comment of the last element in the list
+                // i.e
+                //       var array = [...
+                //          2
+                //          /* end of element 2 */
+                //       ];
+                if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) {
+                    emitLeadingCommentsOfPosition(previousSibling.end);
+                }
+                // Decrease the indent, if requested.
+                if (format & 64 /* Indented */) {
+                    decreaseIndent();
+                }
+                // Write the closing line terminator or closing whitespace.
+                if (shouldWriteClosingLineTerminator(parentNode, children, format)) {
+                    writeLine();
+                }
+                else if (format & 128 /* SpaceBetweenBraces */) {
+                    write(" ");
+                }
+            }
+            if (onAfterEmitNodeArray) {
+                onAfterEmitNodeArray(children);
+            }
+            if (format & 7680 /* BracketsMask */) {
+                write(getClosingBracket(format));
+            }
+        }
+        function write(s) {
+            writer.write(s);
+        }
+        function writeLine() {
+            writer.writeLine();
+        }
+        function increaseIndent() {
+            writer.increaseIndent();
+        }
+        function decreaseIndent() {
+            writer.decreaseIndent();
+        }
+        function writeIfAny(nodes, text) {
+            if (ts.some(nodes)) {
+                write(text);
+            }
+        }
+        function writeToken(token, pos, contextNode) {
+            return onEmitSourceMapOfToken
+                ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
+                : writeTokenText(token, pos);
+        }
+        function writeTokenNode(node) {
+            if (onBeforeEmitToken) {
+                onBeforeEmitToken(node);
+            }
+            write(ts.tokenToString(node.kind));
+            if (onAfterEmitToken) {
+                onAfterEmitToken(node);
+            }
+        }
+        function writeTokenText(token, pos) {
+            var tokenString = ts.tokenToString(token);
+            write(tokenString);
+            return pos < 0 ? pos : pos + tokenString.length;
+        }
+        function writeLineOrSpace(node) {
+            if (ts.getEmitFlags(node) & 1 /* SingleLine */) {
+                write(" ");
+            }
+            else {
+                writeLine();
+            }
+        }
+        function writeLines(text) {
+            var lines = text.split(/\r\n?|\n/g);
+            var indentation = guessIndentation(lines);
+            for (var i = 0; i < lines.length; i++) {
+                var line = indentation ? lines[i].slice(indentation) : lines[i];
+                if (line.length) {
+                    writeLine();
+                    write(line);
+                    writeLine();
+                }
+            }
+        }
+        function guessIndentation(lines) {
+            var indentation;
+            for (var _a = 0, lines_1 = lines; _a < lines_1.length; _a++) {
+                var line = lines_1[_a];
+                for (var i = 0; i < line.length && (indentation === undefined || i < indentation); i++) {
+                    if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
+                        if (indentation === undefined || i < indentation) {
+                            indentation = i;
+                            break;
+                        }
+                    }
+                }
+            }
+            return indentation;
+        }
+        function increaseIndentIf(value, valueToWriteWhenNotIndenting) {
+            if (value) {
+                increaseIndent();
+                writeLine();
+            }
+            else if (valueToWriteWhenNotIndenting) {
+                write(valueToWriteWhenNotIndenting);
+            }
+        }
+        // Helper function to decrease the indent if we previously indented.  Allows multiple
+        // previous indent values to be considered at a time.  This also allows caller to just
+        // call this once, passing in all their appropriate indent values, instead of needing
+        // to call this helper function multiple times.
+        function decreaseIndentIf(value1, value2) {
+            if (value1) {
+                decreaseIndent();
+            }
+            if (value2) {
+                decreaseIndent();
+            }
+        }
+        function shouldWriteLeadingLineTerminator(parentNode, children, format) {
+            if (format & 1 /* MultiLine */) {
+                return true;
+            }
+            if (format & 2 /* PreserveLines */) {
+                if (format & 32768 /* PreferNewLine */) {
+                    return true;
+                }
+                var firstChild = children[0];
+                if (firstChild === undefined) {
+                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
+                }
+                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(firstChild)) {
+                    return synthesizedNodeStartsOnNewLine(firstChild, format);
+                }
+                else {
+                    return !ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile);
+                }
+            }
+            else {
+                return false;
+            }
+        }
+        function shouldWriteSeparatingLineTerminator(previousNode, nextNode, format) {
+            if (format & 1 /* MultiLine */) {
+                return true;
+            }
+            else if (format & 2 /* PreserveLines */) {
+                if (previousNode === undefined || nextNode === undefined) {
+                    return false;
+                }
+                else if (ts.nodeIsSynthesized(previousNode) || ts.nodeIsSynthesized(nextNode)) {
+                    return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format);
+                }
+                else {
+                    return !ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile);
+                }
+            }
+            else {
+                return nextNode.startsOnNewLine;
+            }
+        }
+        function shouldWriteClosingLineTerminator(parentNode, children, format) {
+            if (format & 1 /* MultiLine */) {
+                return (format & 65536 /* NoTrailingNewLine */) === 0;
+            }
+            else if (format & 2 /* PreserveLines */) {
+                if (format & 32768 /* PreferNewLine */) {
+                    return true;
+                }
+                var lastChild = ts.lastOrUndefined(children);
+                if (lastChild === undefined) {
+                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
+                }
+                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(lastChild)) {
+                    return synthesizedNodeStartsOnNewLine(lastChild, format);
+                }
+                else {
+                    return !ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile);
+                }
+            }
+            else {
+                return false;
+            }
+        }
+        function synthesizedNodeStartsOnNewLine(node, format) {
+            if (ts.nodeIsSynthesized(node)) {
+                var startsOnNewLine = node.startsOnNewLine;
+                if (startsOnNewLine === undefined) {
+                    return (format & 32768 /* PreferNewLine */) !== 0;
+                }
+                return startsOnNewLine;
+            }
+            return (format & 32768 /* PreferNewLine */) !== 0;
+        }
+        function needsIndentation(parent, node1, node2) {
+            parent = skipSynthesizedParentheses(parent);
+            node1 = skipSynthesizedParentheses(node1);
+            node2 = skipSynthesizedParentheses(node2);
+            // Always use a newline for synthesized code if the synthesizer desires it.
+            if (node2.startsOnNewLine) {
+                return true;
+            }
+            return !ts.nodeIsSynthesized(parent)
+                && !ts.nodeIsSynthesized(node1)
+                && !ts.nodeIsSynthesized(node2)
+                && !ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile);
+        }
+        function isEmptyBlock(block) {
+            return block.statements.length === 0
+                && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
+        }
+        function skipSynthesizedParentheses(node) {
+            while (node.kind === 185 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) {
+                node = node.expression;
+            }
+            return node;
+        }
+        function getTextOfNode(node, includeTrivia) {
+            if (ts.isGeneratedIdentifier(node)) {
+                return generateName(node);
+            }
+            else if (ts.isIdentifier(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
+                return ts.idText(node);
+            }
+            else if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) {
+                return getTextOfNode(node.textSourceNode, includeTrivia);
+            }
+            else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
+                return node.text;
+            }
+            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
+        }
+        function getLiteralTextOfNode(node) {
+            if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) {
+                var textSourceNode = node.textSourceNode;
+                if (ts.isIdentifier(textSourceNode)) {
+                    return ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ?
+                        "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" :
+                        "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\"";
+                }
+                else {
+                    return getLiteralTextOfNode(textSourceNode);
+                }
+            }
+            return ts.getLiteralText(node, currentSourceFile);
+        }
+        /**
+         * Push a new name generation scope.
+         */
+        function pushNameGenerationScope() {
+            tempFlagsStack.push(tempFlags);
+            tempFlags = 0;
+        }
+        /**
+         * Pop the current name generation scope.
+         */
+        function popNameGenerationScope() {
+            tempFlags = tempFlagsStack.pop();
+        }
+        /**
+         * Generate the text for a generated identifier.
+         */
+        function generateName(name) {
+            if (name.autoGenerateKind === 4 /* Node */) {
+                // Node names generate unique names based on their original node
+                // and are cached based on that node's id.
+                var node = getNodeForGeneratedName(name);
+                return generateNameCached(node);
+            }
+            else {
+                // Auto, Loop, and Unique names are cached based on their unique
+                // autoGenerateId.
+                var autoGenerateId = name.autoGenerateId;
+                return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
+            }
+        }
+        function generateNameCached(node) {
+            var nodeId = ts.getNodeId(node);
+            return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node));
+        }
+        /**
+         * Returns a value indicating whether a name is unique globally, within the current file,
+         * or within the NameGenerator.
+         */
+        function isUniqueName(name) {
+            return !(hasGlobalName && hasGlobalName(name))
+                && !currentSourceFile.identifiers.has(name)
+                && !generatedNames.has(name);
+        }
+        /**
+         * Returns a value indicating whether a name is unique within a container.
+         */
+        function isUniqueLocalName(name, container) {
+            for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) {
+                if (node.locals) {
+                    var local = node.locals.get(ts.escapeLeadingUnderscores(name));
+                    // We conservatively include alias symbols to cover cases where they're emitted as locals
+                    if (local && local.flags & (107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        /**
+         * Return the next available name in the pattern _a ... _z, _0, _1, ...
+         * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
+         * Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
+         */
+        function makeTempVariableName(flags) {
+            if (flags && !(tempFlags & flags)) {
+                var name = flags === 268435456 /* _i */ ? "_i" : "_n";
+                if (isUniqueName(name)) {
+                    tempFlags |= flags;
+                    return name;
+                }
+            }
+            while (true) {
+                var count = tempFlags & 268435455 /* CountMask */;
+                tempFlags++;
+                // Skip over 'i' and 'n'
+                if (count !== 8 && count !== 13) {
+                    var name = count < 26
+                        ? "_" + String.fromCharCode(97 /* a */ + count)
+                        : "_" + (count - 26);
+                    if (isUniqueName(name)) {
+                        return name;
+                    }
+                }
+            }
+        }
+        /**
+         * Generate a name that is unique within the current file and doesn't conflict with any names
+         * in global scope. The name is formed by adding an '_n' suffix to the specified base name,
+         * where n is a positive integer. Note that names generated by makeTempVariableName and
+         * makeUniqueName are guaranteed to never conflict.
+         */
+        function makeUniqueName(baseName) {
+            // Find the first unique 'name_n', where n is a positive number
+            if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
+                baseName += "_";
+            }
+            var i = 1;
+            while (true) {
+                var generatedName = baseName + i;
+                if (isUniqueName(generatedName)) {
+                    generatedNames.set(generatedName, true);
+                    return generatedName;
+                }
+                i++;
+            }
+        }
+        /**
+         * Generates a unique name for a ModuleDeclaration or EnumDeclaration.
+         */
+        function generateNameForModuleOrEnum(node) {
+            var name = getTextOfNode(node.name);
+            // Use module/enum name itself if it is unique, otherwise make a unique variation
+            return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
+        }
+        /**
+         * Generates a unique name for an ImportDeclaration or ExportDeclaration.
+         */
+        function generateNameForImportOrExportDeclaration(node) {
+            var expr = ts.getExternalModuleName(node);
+            var baseName = ts.isStringLiteral(expr) ?
+                ts.makeIdentifierFromModuleName(expr.text) : "module";
+            return makeUniqueName(baseName);
+        }
+        /**
+         * Generates a unique name for a default export.
+         */
+        function generateNameForExportDefault() {
+            return makeUniqueName("default");
+        }
+        /**
+         * Generates a unique name for a class expression.
+         */
+        function generateNameForClassExpression() {
+            return makeUniqueName("class");
+        }
+        function generateNameForMethodOrAccessor(node) {
+            if (ts.isIdentifier(node.name)) {
+                return generateNameCached(node.name);
+            }
+            return makeTempVariableName(0 /* Auto */);
+        }
+        /**
+         * Generates a unique name from a node.
+         */
+        function generateNameForNode(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                    return makeUniqueName(getTextOfNode(node));
+                case 233 /* ModuleDeclaration */:
+                case 232 /* EnumDeclaration */:
+                    return generateNameForModuleOrEnum(node);
+                case 238 /* ImportDeclaration */:
+                case 244 /* ExportDeclaration */:
+                    return generateNameForImportOrExportDeclaration(node);
+                case 228 /* FunctionDeclaration */:
+                case 229 /* ClassDeclaration */:
+                case 243 /* ExportAssignment */:
+                    return generateNameForExportDefault();
+                case 199 /* ClassExpression */:
+                    return generateNameForClassExpression();
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                    return generateNameForMethodOrAccessor(node);
+                default:
+                    return makeTempVariableName(0 /* Auto */);
+            }
+        }
+        /**
+         * Generates a unique identifier for a node.
+         */
+        function makeName(name) {
+            switch (name.autoGenerateKind) {
+                case 1 /* Auto */:
+                    return makeTempVariableName(0 /* Auto */);
+                case 2 /* Loop */:
+                    return makeTempVariableName(268435456 /* _i */);
+                case 3 /* Unique */:
+                    return makeUniqueName(ts.idText(name));
+            }
+            ts.Debug.fail("Unsupported GeneratedIdentifierKind.");
+        }
+        /**
+         * Gets the node from which a name should be generated.
+         */
+        function getNodeForGeneratedName(name) {
+            var autoGenerateId = name.autoGenerateId;
+            var node = name;
+            var original = node.original;
+            while (original) {
+                node = original;
+                // if "node" is a different generated name (having a different
+                // "autoGenerateId"), use it and stop traversing.
+                if (ts.isIdentifier(node)
+                    && node.autoGenerateKind === 4 /* Node */
+                    && node.autoGenerateId !== autoGenerateId) {
+                    break;
+                }
+                original = node.original;
+            }
+            // otherwise, return the original node for the source;
+            return node;
+        }
+    }
+    ts.createPrinter = createPrinter;
+    function createDelimiterMap() {
+        var delimiters = [];
+        delimiters[0 /* None */] = "";
+        delimiters[16 /* CommaDelimited */] = ",";
+        delimiters[4 /* BarDelimited */] = " |";
+        delimiters[8 /* AmpersandDelimited */] = " &";
+        return delimiters;
+    }
+    function getDelimiter(format) {
+        return delimiters[format & 28 /* DelimitersMask */];
+    }
+    function createBracketsMap() {
+        var brackets = [];
+        brackets[512 /* Braces */] = ["{", "}"];
+        brackets[1024 /* Parenthesis */] = ["(", ")"];
+        brackets[2048 /* AngleBrackets */] = ["<", ">"];
+        brackets[4096 /* SquareBrackets */] = ["[", "]"];
+        return brackets;
+    }
+    function getOpeningBracket(format) {
+        return brackets[format & 7680 /* BracketsMask */][0];
+    }
+    function getClosingBracket(format) {
+        return brackets[format & 7680 /* BracketsMask */][1];
+    }
+    // Flags enum to track count of temp variables and a few dedicated names
+    var TempFlags;
+    (function (TempFlags) {
+        TempFlags[TempFlags["Auto"] = 0] = "Auto";
+        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
+        TempFlags[TempFlags["_i"] = 268435456] = "_i";
+    })(TempFlags || (TempFlags = {}));
+    var ListFormat;
+    (function (ListFormat) {
+        ListFormat[ListFormat["None"] = 0] = "None";
+        // Line separators
+        ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine";
+        ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine";
+        ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines";
+        ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask";
+        // Delimiters
+        ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited";
+        ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited";
+        ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited";
+        ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited";
+        ListFormat[ListFormat["DelimitersMask"] = 28] = "DelimitersMask";
+        ListFormat[ListFormat["AllowTrailingComma"] = 32] = "AllowTrailingComma";
+        // Whitespace
+        ListFormat[ListFormat["Indented"] = 64] = "Indented";
+        ListFormat[ListFormat["SpaceBetweenBraces"] = 128] = "SpaceBetweenBraces";
+        ListFormat[ListFormat["SpaceBetweenSiblings"] = 256] = "SpaceBetweenSiblings";
+        // Brackets/Braces
+        ListFormat[ListFormat["Braces"] = 512] = "Braces";
+        ListFormat[ListFormat["Parenthesis"] = 1024] = "Parenthesis";
+        ListFormat[ListFormat["AngleBrackets"] = 2048] = "AngleBrackets";
+        ListFormat[ListFormat["SquareBrackets"] = 4096] = "SquareBrackets";
+        ListFormat[ListFormat["BracketsMask"] = 7680] = "BracketsMask";
+        ListFormat[ListFormat["OptionalIfUndefined"] = 8192] = "OptionalIfUndefined";
+        ListFormat[ListFormat["OptionalIfEmpty"] = 16384] = "OptionalIfEmpty";
+        ListFormat[ListFormat["Optional"] = 24576] = "Optional";
+        // Other
+        ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine";
+        ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine";
+        ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments";
+        ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty";
+        ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement";
+        // Precomputed Formats
+        ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers";
+        ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses";
+        ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 448] = "SingleLineTypeLiteralMembers";
+        ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 65] = "MultiLineTypeLiteralMembers";
+        ListFormat[ListFormat["TupleTypeElements"] = 336] = "TupleTypeElements";
+        ListFormat[ListFormat["UnionTypeConstituents"] = 260] = "UnionTypeConstituents";
+        ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents";
+        ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements";
+        ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements";
+        ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties";
+        ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements";
+        ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements";
+        ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments";
+        ListFormat[ListFormat["NewExpressionArguments"] = 9488] = "NewExpressionArguments";
+        ListFormat[ListFormat["TemplateExpressionSpans"] = 131072] = "TemplateExpressionSpans";
+        ListFormat[ListFormat["SingleLineBlockStatements"] = 384] = "SingleLineBlockStatements";
+        ListFormat[ListFormat["MultiLineBlockStatements"] = 65] = "MultiLineBlockStatements";
+        ListFormat[ListFormat["VariableDeclarationList"] = 272] = "VariableDeclarationList";
+        ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 384] = "SingleLineFunctionBodyStatements";
+        ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements";
+        ListFormat[ListFormat["ClassHeritageClauses"] = 256] = "ClassHeritageClauses";
+        ListFormat[ListFormat["ClassMembers"] = 65] = "ClassMembers";
+        ListFormat[ListFormat["InterfaceMembers"] = 65] = "InterfaceMembers";
+        ListFormat[ListFormat["EnumMembers"] = 81] = "EnumMembers";
+        ListFormat[ListFormat["CaseBlockClauses"] = 65] = "CaseBlockClauses";
+        ListFormat[ListFormat["NamedImportsOrExportsElements"] = 432] = "NamedImportsOrExportsElements";
+        ListFormat[ListFormat["JsxElementChildren"] = 131072] = "JsxElementChildren";
+        ListFormat[ListFormat["JsxElementAttributes"] = 131328] = "JsxElementAttributes";
+        ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 81985] = "CaseOrDefaultClauseStatements";
+        ListFormat[ListFormat["HeritageClauseTypes"] = 272] = "HeritageClauseTypes";
+        ListFormat[ListFormat["SourceFileStatements"] = 65537] = "SourceFileStatements";
+        ListFormat[ListFormat["Decorators"] = 24577] = "Decorators";
+        ListFormat[ListFormat["TypeArguments"] = 26960] = "TypeArguments";
+        ListFormat[ListFormat["TypeParameters"] = 26960] = "TypeParameters";
+        ListFormat[ListFormat["Parameters"] = 1360] = "Parameters";
+        ListFormat[ListFormat["IndexSignatureParameters"] = 4432] = "IndexSignatureParameters";
+    })(ListFormat || (ListFormat = {}));
+})(ts || (ts = {}));
+/// <reference path="program.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers) {
+        var outputFiles = [];
+        var emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
+        return { outputFiles: outputFiles, emitSkipped: emitResult.emitSkipped };
+        function writeFile(fileName, text, writeByteOrderMark) {
+            outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text });
+        }
+    }
+    ts.getFileEmitOutput = getFileEmitOutput;
+    function createBuilder(options) {
+        var isModuleEmit;
+        var fileInfos = ts.createMap();
+        var semanticDiagnosticsPerFile = ts.createMap();
+        /** The map has key by source file's path that has been changed */
+        var changedFilesSet = ts.createMap();
+        var hasShapeChanged = ts.createMap();
+        var allFilesExcludingDefaultLibraryFile;
+        var emitHandler;
+        return {
+            updateProgram: updateProgram,
+            getFilesAffectedBy: getFilesAffectedBy,
+            emitChangedFiles: emitChangedFiles,
+            getSemanticDiagnostics: getSemanticDiagnostics,
+            clear: clear
+        };
+        function createProgramGraph(program) {
+            var currentIsModuleEmit = program.getCompilerOptions().module !== ts.ModuleKind.None;
+            if (isModuleEmit !== currentIsModuleEmit) {
+                isModuleEmit = currentIsModuleEmit;
+                emitHandler = isModuleEmit ? getModuleEmitHandler() : getNonModuleEmitHandler();
+                fileInfos.clear();
+                semanticDiagnosticsPerFile.clear();
+            }
+            hasShapeChanged.clear();
+            allFilesExcludingDefaultLibraryFile = undefined;
+            ts.mutateMap(fileInfos, ts.arrayToMap(program.getSourceFiles(), function (sourceFile) { return sourceFile.path; }), {
+                // Add new file info
+                createNewValue: function (_path, sourceFile) { return addNewFileInfo(program, sourceFile); },
+                // Remove existing file info
+                onDeleteValue: removeExistingFileInfo,
+                // We will update in place instead of deleting existing value and adding new one
+                onExistingValue: function (existingInfo, sourceFile) { return updateExistingFileInfo(program, existingInfo, sourceFile); }
+            });
+        }
+        function registerChangedFile(path) {
+            changedFilesSet.set(path, true);
+            // All changed files need to re-evaluate its semantic diagnostics
+            semanticDiagnosticsPerFile.delete(path);
+        }
+        function addNewFileInfo(program, sourceFile) {
+            registerChangedFile(sourceFile.path);
+            emitHandler.onAddSourceFile(program, sourceFile);
+            return { version: sourceFile.version, signature: undefined };
+        }
+        function removeExistingFileInfo(_existingFileInfo, path) {
+            // Since we dont need to track removed file as changed file
+            // We can just remove its diagnostics
+            changedFilesSet.delete(path);
+            semanticDiagnosticsPerFile.delete(path);
+            emitHandler.onRemoveSourceFile(path);
+        }
+        function updateExistingFileInfo(program, existingInfo, sourceFile) {
+            if (existingInfo.version !== sourceFile.version) {
+                registerChangedFile(sourceFile.path);
+                existingInfo.version = sourceFile.version;
+                emitHandler.onUpdateSourceFile(program, sourceFile);
+            }
+            else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
+                registerChangedFile(sourceFile.path);
+            }
+        }
+        function ensureProgramGraph(program) {
+            if (!emitHandler) {
+                createProgramGraph(program);
+            }
+        }
+        function updateProgram(newProgram) {
+            if (emitHandler) {
+                createProgramGraph(newProgram);
+            }
+        }
+        function getFilesAffectedBy(program, path) {
+            ensureProgramGraph(program);
+            var sourceFile = program.getSourceFileByPath(path);
+            if (!sourceFile) {
+                return ts.emptyArray;
+            }
+            if (!updateShapeSignature(program, sourceFile)) {
+                return [sourceFile];
+            }
+            return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile);
+        }
+        function emitChangedFiles(program, writeFileCallback) {
+            ensureProgramGraph(program);
+            var compilerOptions = program.getCompilerOptions();
+            if (!changedFilesSet.size) {
+                return ts.emptyArray;
+            }
+            // With --out or --outFile all outputs go into single file, do it only once
+            if (compilerOptions.outFile || compilerOptions.out) {
+                ts.Debug.assert(semanticDiagnosticsPerFile.size === 0);
+                changedFilesSet.clear();
+                return [program.emit(/*targetSourceFile*/ undefined, writeFileCallback)];
+            }
+            var seenFiles = ts.createMap();
+            var result;
+            changedFilesSet.forEach(function (_true, path) {
+                // Get the affected Files by this program
+                var affectedFiles = getFilesAffectedBy(program, path);
+                affectedFiles.forEach(function (affectedFile) {
+                    // Affected files shouldnt have cached diagnostics
+                    semanticDiagnosticsPerFile.delete(affectedFile.path);
+                    if (!seenFiles.has(affectedFile.path)) {
+                        seenFiles.set(affectedFile.path, true);
+                        // Emit the affected file
+                        (result || (result = [])).push(program.emit(affectedFile, writeFileCallback));
+                    }
+                });
+            });
+            changedFilesSet.clear();
+            return result || ts.emptyArray;
+        }
+        function getSemanticDiagnostics(program, cancellationToken) {
+            ensureProgramGraph(program);
+            ts.Debug.assert(changedFilesSet.size === 0);
+            var compilerOptions = program.getCompilerOptions();
+            if (compilerOptions.outFile || compilerOptions.out) {
+                ts.Debug.assert(semanticDiagnosticsPerFile.size === 0);
+                // We dont need to cache the diagnostics just return them from program
+                return program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken);
+            }
+            var diagnostics;
+            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
+                var sourceFile = _a[_i];
+                diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken));
+            }
+            return diagnostics || ts.emptyArray;
+        }
+        function getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken) {
+            var path = sourceFile.path;
+            var cachedDiagnostics = semanticDiagnosticsPerFile.get(path);
+            // Report the semantic diagnostics from the cache if we already have those diagnostics present
+            if (cachedDiagnostics) {
+                return cachedDiagnostics;
+            }
+            // Diagnostics werent cached, get them from program, and cache the result
+            var diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken);
+            semanticDiagnosticsPerFile.set(path, diagnostics);
+            return diagnostics;
+        }
+        function clear() {
+            isModuleEmit = undefined;
+            emitHandler = undefined;
+            fileInfos.clear();
+            semanticDiagnosticsPerFile.clear();
+            changedFilesSet.clear();
+            hasShapeChanged.clear();
+        }
+        /**
+         * For script files that contains only ambient external modules, although they are not actually external module files,
+         * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
+         * there are no point to rebuild all script files if these special files have changed. However, if any statement
+         * in the file is not ambient external module, we treat it as a regular script file.
+         */
+        function containsOnlyAmbientModules(sourceFile) {
+            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
+                var statement = _a[_i];
+                if (!ts.isModuleWithStringLiteralName(statement)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        /**
+         * @return {boolean} indicates if the shape signature has changed since last update.
+         */
+        function updateShapeSignature(program, sourceFile) {
+            ts.Debug.assert(!!sourceFile);
+            // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
+            if (hasShapeChanged.has(sourceFile.path)) {
+                return false;
+            }
+            hasShapeChanged.set(sourceFile.path, true);
+            var info = fileInfos.get(sourceFile.path);
+            ts.Debug.assert(!!info);
+            var prevSignature = info.signature;
+            var latestSignature;
+            if (sourceFile.isDeclarationFile) {
+                latestSignature = sourceFile.version;
+                info.signature = latestSignature;
+            }
+            else {
+                var emitOutput = getFileEmitOutput(program, sourceFile, /*emitOnlyDtsFiles*/ true);
+                if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
+                    latestSignature = options.computeHash(emitOutput.outputFiles[0].text);
+                    info.signature = latestSignature;
+                }
+                else {
+                    latestSignature = prevSignature;
+                }
+            }
+            return !prevSignature || latestSignature !== prevSignature;
+        }
+        /**
+         * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
+         */
+        function getReferencedFiles(program, sourceFile) {
+            var referencedFiles;
+            // We need to use a set here since the code can contain the same import twice,
+            // but that will only be one dependency.
+            // To avoid invernal conversion, the key of the referencedFiles map must be of type Path
+            if (sourceFile.imports && sourceFile.imports.length > 0) {
+                var checker = program.getTypeChecker();
+                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
+                    var importName = _a[_i];
+                    var symbol = checker.getSymbolAtLocation(importName);
+                    if (symbol && symbol.declarations && symbol.declarations[0]) {
+                        var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]);
+                        if (declarationSourceFile) {
+                            addReferencedFile(declarationSourceFile.path);
+                        }
+                    }
+                }
+            }
+            var sourceFileDirectory = ts.getDirectoryPath(sourceFile.path);
+            // Handle triple slash references
+            if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
+                for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) {
+                    var referencedFile = _c[_b];
+                    var referencedPath = ts.toPath(referencedFile.fileName, sourceFileDirectory, options.getCanonicalFileName);
+                    addReferencedFile(referencedPath);
+                }
+            }
+            // Handle type reference directives
+            if (sourceFile.resolvedTypeReferenceDirectiveNames) {
+                sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) {
+                    if (!resolvedTypeReferenceDirective) {
+                        return;
+                    }
+                    var fileName = resolvedTypeReferenceDirective.resolvedFileName;
+                    var typeFilePath = ts.toPath(fileName, sourceFileDirectory, options.getCanonicalFileName);
+                    addReferencedFile(typeFilePath);
+                });
+            }
+            return referencedFiles;
+            function addReferencedFile(referencedPath) {
+                if (!referencedFiles) {
+                    referencedFiles = ts.createMap();
+                }
+                referencedFiles.set(referencedPath, true);
+            }
+        }
+        /**
+         * Gets all files of the program excluding the default library file
+         */
+        function getAllFilesExcludingDefaultLibraryFile(program, firstSourceFile) {
+            // Use cached result
+            if (allFilesExcludingDefaultLibraryFile) {
+                return allFilesExcludingDefaultLibraryFile;
+            }
+            var result;
+            addSourceFile(firstSourceFile);
+            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
+                var sourceFile = _a[_i];
+                if (sourceFile !== firstSourceFile) {
+                    addSourceFile(sourceFile);
+                }
+            }
+            allFilesExcludingDefaultLibraryFile = result || ts.emptyArray;
+            return allFilesExcludingDefaultLibraryFile;
+            function addSourceFile(sourceFile) {
+                if (!program.isSourceFileDefaultLibrary(sourceFile)) {
+                    (result || (result = [])).push(sourceFile);
+                }
+            }
+        }
+        function getNonModuleEmitHandler() {
+            return {
+                onAddSourceFile: ts.noop,
+                onRemoveSourceFile: ts.noop,
+                onUpdateSourceFile: ts.noop,
+                onUpdateSourceFileWithSameVersion: ts.returnFalse,
+                getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape
+            };
+            function getFilesAffectedByUpdatedShape(program, sourceFile) {
+                var options = program.getCompilerOptions();
+                // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
+                // so returning the file itself is good enough.
+                if (options && (options.out || options.outFile)) {
+                    return [sourceFile];
+                }
+                return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
+            }
+        }
+        function getModuleEmitHandler() {
+            var references = ts.createMap();
+            return {
+                onAddSourceFile: setReferences,
+                onRemoveSourceFile: onRemoveSourceFile,
+                onUpdateSourceFile: updateReferences,
+                onUpdateSourceFileWithSameVersion: updateReferencesTrackingChangedReferences,
+                getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape
+            };
+            function setReferences(program, sourceFile) {
+                var newReferences = getReferencedFiles(program, sourceFile);
+                if (newReferences) {
+                    references.set(sourceFile.path, newReferences);
+                }
+            }
+            function updateReferences(program, sourceFile) {
+                var newReferences = getReferencedFiles(program, sourceFile);
+                if (newReferences) {
+                    references.set(sourceFile.path, newReferences);
+                }
+                else {
+                    references.delete(sourceFile.path);
+                }
+            }
+            function updateReferencesTrackingChangedReferences(program, sourceFile) {
+                var newReferences = getReferencedFiles(program, sourceFile);
+                if (!newReferences) {
+                    // Changed if we had references
+                    return references.delete(sourceFile.path);
+                }
+                var oldReferences = references.get(sourceFile.path);
+                references.set(sourceFile.path, newReferences);
+                if (!oldReferences || oldReferences.size !== newReferences.size) {
+                    return true;
+                }
+                // If there are any new references that werent present previously there is change
+                return ts.forEachEntry(newReferences, function (_true, referencedPath) { return !oldReferences.delete(referencedPath); }) ||
+                    // Otherwise its changed if there are more references previously than now
+                    !!oldReferences.size;
+            }
+            function onRemoveSourceFile(removedFilePath) {
+                // Remove existing references
+                references.forEach(function (referencesInFile, filePath) {
+                    if (referencesInFile.has(removedFilePath)) {
+                        // add files referencing the removedFilePath, as changed files too
+                        var referencedByInfo = fileInfos.get(filePath);
+                        if (referencedByInfo) {
+                            registerChangedFile(filePath);
+                        }
+                    }
+                });
+                // Delete the entry for the removed file path
+                references.delete(removedFilePath);
+            }
+            function getReferencedByPaths(referencedFilePath) {
+                return ts.mapDefinedIter(references.entries(), function (_a) {
+                    var filePath = _a[0], referencesInFile = _a[1];
+                    return referencesInFile.has(referencedFilePath) ? filePath : undefined;
+                });
+            }
+            function getFilesAffectedByUpdatedShape(program, sourceFile) {
+                if (!ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile)) {
+                    return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
+                }
+                var compilerOptions = program.getCompilerOptions();
+                if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
+                    return [sourceFile];
+                }
+                // Now we need to if each file in the referencedBy list has a shape change as well.
+                // Because if so, its own referencedBy files need to be saved as well to make the
+                // emitting result consistent with files on disk.
+                var seenFileNamesMap = ts.createMap();
+                // Start with the paths this file was referenced by
+                var path = sourceFile.path;
+                seenFileNamesMap.set(path, sourceFile);
+                var queue = getReferencedByPaths(path);
+                while (queue.length > 0) {
+                    var currentPath = queue.pop();
+                    if (!seenFileNamesMap.has(currentPath)) {
+                        var currentSourceFile = program.getSourceFileByPath(currentPath);
+                        seenFileNamesMap.set(currentPath, currentSourceFile);
+                        if (currentSourceFile && updateShapeSignature(program, currentSourceFile)) {
+                            queue.push.apply(queue, getReferencedByPaths(currentPath));
+                        }
+                    }
+                }
+                // Return array of values that needs emit
+                return ts.flatMapIter(seenFileNamesMap.values(), function (value) { return value; });
+            }
+        }
+    }
+    ts.createBuilder = createBuilder;
+})(ts || (ts = {}));
+/// <reference path="sys.ts" />
+/// <reference path="emitter.ts" />
+/// <reference path="core.ts" />
+/// <reference path="builder.ts" />
+var ts;
+(function (ts) {
+    var ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
+    function findConfigFile(searchPath, fileExists, configName) {
+        if (configName === void 0) { configName = "tsconfig.json"; }
+        while (true) {
+            var fileName = ts.combinePaths(searchPath, configName);
+            if (fileExists(fileName)) {
+                return fileName;
+            }
+            var parentPath = ts.getDirectoryPath(searchPath);
+            if (parentPath === searchPath) {
+                break;
+            }
+            searchPath = parentPath;
+        }
+        return undefined;
+    }
+    ts.findConfigFile = findConfigFile;
+    function resolveTripleslashReference(moduleName, containingFile) {
+        var basePath = ts.getDirectoryPath(containingFile);
+        var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName);
+        return ts.normalizePath(referencedFileName);
+    }
+    ts.resolveTripleslashReference = resolveTripleslashReference;
+    /* @internal */
+    function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
+        var commonPathComponents;
+        var failed = ts.forEach(fileNames, function (sourceFile) {
+            // Each file contributes into common source file path
+            var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory);
+            sourcePathComponents.pop(); // The base file name is not part of the common directory path
+            if (!commonPathComponents) {
+                // first file
+                commonPathComponents = sourcePathComponents;
+                return;
+            }
+            var n = Math.min(commonPathComponents.length, sourcePathComponents.length);
+            for (var i = 0; i < n; i++) {
+                if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
+                    if (i === 0) {
+                        // Failed to find any common path component
+                        return true;
+                    }
+                    // New common path found that is 0 -> i-1
+                    commonPathComponents.length = i;
+                    break;
+                }
+            }
+            // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
+            if (sourcePathComponents.length < commonPathComponents.length) {
+                commonPathComponents.length = sourcePathComponents.length;
+            }
+        });
+        // A common path can not be found when paths span multiple drives on windows, for example
+        if (failed) {
+            return "";
+        }
+        if (!commonPathComponents) {
+            return currentDirectory;
+        }
+        return ts.getNormalizedPathFromPathComponents(commonPathComponents);
+    }
+    ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames;
+    function createCompilerHost(options, setParentNodes) {
+        var existingDirectories = ts.createMap();
+        function getCanonicalFileName(fileName) {
+            // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
+            // otherwise use toLowerCase as a canonical form.
+            return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
+        }
+        function getSourceFile(fileName, languageVersion, onError) {
+            var text;
+            try {
+                ts.performance.mark("beforeIORead");
+                text = ts.sys.readFile(fileName, options.charset);
+                ts.performance.mark("afterIORead");
+                ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message);
+                }
+                text = "";
+            }
+            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
+        }
+        function directoryExists(directoryPath) {
+            if (existingDirectories.has(directoryPath)) {
+                return true;
+            }
+            if (ts.sys.directoryExists(directoryPath)) {
+                existingDirectories.set(directoryPath, true);
+                return true;
+            }
+            return false;
+        }
+        function ensureDirectoriesExist(directoryPath) {
+            if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) {
+                var parentDirectory = ts.getDirectoryPath(directoryPath);
+                ensureDirectoriesExist(parentDirectory);
+                ts.sys.createDirectory(directoryPath);
+            }
+        }
+        var outputFingerprints;
+        function writeFileIfUpdated(fileName, data, writeByteOrderMark) {
+            if (!outputFingerprints) {
+                outputFingerprints = ts.createMap();
+            }
+            var hash = ts.sys.createHash(data);
+            var mtimeBefore = ts.sys.getModifiedTime(fileName);
+            if (mtimeBefore) {
+                var fingerprint = outputFingerprints.get(fileName);
+                // If output has not been changed, and the file has no external modification
+                if (fingerprint &&
+                    fingerprint.byteOrderMark === writeByteOrderMark &&
+                    fingerprint.hash === hash &&
+                    fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
+                    return;
+                }
+            }
+            ts.sys.writeFile(fileName, data, writeByteOrderMark);
+            var mtimeAfter = ts.sys.getModifiedTime(fileName);
+            outputFingerprints.set(fileName, {
+                hash: hash,
+                byteOrderMark: writeByteOrderMark,
+                mtime: mtimeAfter
+            });
+        }
+        function writeFile(fileName, data, writeByteOrderMark, onError) {
+            try {
+                ts.performance.mark("beforeIOWrite");
+                ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(fileName)));
+                if (ts.isWatchSet(options) && ts.sys.createHash && ts.sys.getModifiedTime) {
+                    writeFileIfUpdated(fileName, data, writeByteOrderMark);
+                }
+                else {
+                    ts.sys.writeFile(fileName, data, writeByteOrderMark);
+                }
+                ts.performance.mark("afterIOWrite");
+                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message);
+                }
+            }
+        }
+        function getDefaultLibLocation() {
+            return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath()));
+        }
+        var newLine = ts.getNewLineCharacter(options);
+        var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); });
+        return {
+            getSourceFile: getSourceFile,
+            getDefaultLibLocation: getDefaultLibLocation,
+            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
+            writeFile: writeFile,
+            getCurrentDirectory: ts.memoize(function () { return ts.sys.getCurrentDirectory(); }),
+            useCaseSensitiveFileNames: function () { return ts.sys.useCaseSensitiveFileNames; },
+            getCanonicalFileName: getCanonicalFileName,
+            getNewLine: function () { return newLine; },
+            fileExists: function (fileName) { return ts.sys.fileExists(fileName); },
+            readFile: function (fileName) { return ts.sys.readFile(fileName); },
+            trace: function (s) { return ts.sys.write(s + newLine); },
+            directoryExists: function (directoryName) { return ts.sys.directoryExists(directoryName); },
+            getEnvironmentVariable: function (name) { return ts.sys.getEnvironmentVariable ? ts.sys.getEnvironmentVariable(name) : ""; },
+            getDirectories: function (path) { return ts.sys.getDirectories(path); },
+            realpath: realpath
+        };
+    }
+    ts.createCompilerHost = createCompilerHost;
+    function getPreEmitDiagnostics(program, sourceFile, cancellationToken) {
+        var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
+        if (program.getCompilerOptions().declaration) {
+            ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
+        }
+        return ts.sortAndDeduplicateDiagnostics(diagnostics);
+    }
+    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
+    function formatDiagnostics(diagnostics, host) {
+        var output = "";
+        for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) {
+            var diagnostic = diagnostics_1[_i];
+            output += formatDiagnostic(diagnostic, host);
+        }
+        return output;
+    }
+    ts.formatDiagnostics = formatDiagnostics;
+    function formatDiagnostic(diagnostic, host) {
+        var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
+        var errorMessage = category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine();
+        if (diagnostic.file) {
+            var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character;
+            var fileName = diagnostic.file.fileName;
+            var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); });
+            return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage;
+        }
+        return errorMessage;
+    }
+    ts.formatDiagnostic = formatDiagnostic;
+    var redForegroundEscapeSequence = "\u001b[91m";
+    var yellowForegroundEscapeSequence = "\u001b[93m";
+    var blueForegroundEscapeSequence = "\u001b[93m";
+    var gutterStyleSequence = "\u001b[30;47m";
+    var gutterSeparator = " ";
+    var resetEscapeSequence = "\u001b[0m";
+    var ellipsis = "...";
+    function getCategoryFormat(category) {
+        switch (category) {
+            case ts.DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
+            case ts.DiagnosticCategory.Error: return redForegroundEscapeSequence;
+            case ts.DiagnosticCategory.Message: return blueForegroundEscapeSequence;
+        }
+    }
+    function formatAndReset(text, formatStyle) {
+        return formatStyle + text + resetEscapeSequence;
+    }
+    function padLeft(s, length) {
+        while (s.length < length) {
+            s = " " + s;
+        }
+        return s;
+    }
+    function formatDiagnosticsWithColorAndContext(diagnostics, host) {
+        var output = "";
+        for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) {
+            var diagnostic = diagnostics_2[_i];
+            var context = "";
+            if (diagnostic.file) {
+                var start = diagnostic.start, length_5 = diagnostic.length, file = diagnostic.file;
+                var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
+                var _b = ts.getLineAndCharacterOfPosition(file, start + length_5), lastLine = _b.line, lastLineChar = _b.character;
+                var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
+                var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName;
+                var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
+                var gutterWidth = (lastLine + 1 + "").length;
+                if (hasMoreThanFiveLines) {
+                    gutterWidth = Math.max(ellipsis.length, gutterWidth);
+                }
+                context += host.getNewLine();
+                for (var i = firstLine; i <= lastLine; i++) {
+                    // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
+                    // so we'll skip ahead to the second-to-last line.
+                    if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
+                        context += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
+                        i = lastLine - 1;
+                    }
+                    var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0);
+                    var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
+                    var lineContent = file.text.slice(lineStart, lineEnd);
+                    lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
+                    lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
+                    // Output the gutter and the actual contents of the line.
+                    context += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
+                    context += lineContent + host.getNewLine();
+                    // Output the gutter and the error span for the line using tildes.
+                    context += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
+                    context += redForegroundEscapeSequence;
+                    if (i === firstLine) {
+                        // If we're on the last line, then limit it to the last character of the last line.
+                        // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
+                        var lastCharForLine = i === lastLine ? lastLineChar : undefined;
+                        context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
+                        context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
+                    }
+                    else if (i === lastLine) {
+                        context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
+                    }
+                    else {
+                        // Squiggle the entire line.
+                        context += lineContent.replace(/./g, "~");
+                    }
+                    context += resetEscapeSequence;
+                }
+                output += host.getNewLine();
+                output += relativeFileName + "(" + (firstLine + 1) + "," + (firstLineChar + 1) + "): ";
+            }
+            var categoryColor = getCategoryFormat(diagnostic.category);
+            var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
+            output += formatAndReset(category, categoryColor) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
+            if (diagnostic.file) {
+                output += host.getNewLine();
+                output += context;
+            }
+            output += host.getNewLine();
+        }
+        return output;
+    }
+    ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext;
+    function flattenDiagnosticMessageText(messageText, newLine) {
+        if (ts.isString(messageText)) {
+            return messageText;
+        }
+        else {
+            var diagnosticChain = messageText;
+            var result = "";
+            var indent = 0;
+            while (diagnosticChain) {
+                if (indent) {
+                    result += newLine;
+                    for (var i = 0; i < indent; i++) {
+                        result += "  ";
+                    }
+                }
+                result += diagnosticChain.messageText;
+                indent++;
+                diagnosticChain = diagnosticChain.next;
+            }
+            return result;
+        }
+    }
+    ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText;
+    function loadWithLocalCache(names, containingFile, loader) {
+        if (names.length === 0) {
+            return [];
+        }
+        var resolutions = [];
+        var cache = ts.createMap();
+        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
+            var name = names_1[_i];
+            var result = void 0;
+            if (cache.has(name)) {
+                result = cache.get(name);
+            }
+            else {
+                cache.set(name, result = loader(name, containingFile));
+            }
+            resolutions.push(result);
+        }
+        return resolutions;
+    }
+    /**
+     * Determines if program structure is upto date or needs to be recreated
+     */
+    /* @internal */
+    function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames) {
+        // If we haven't create a program yet or has changed automatic type directives, then it is not up-to-date
+        if (!program || hasChangedAutomaticTypeDirectiveNames) {
+            return false;
+        }
+        // If number of files in the program do not match, it is not up-to-date
+        if (program.getRootFileNames().length !== rootFileNames.length) {
+            return false;
+        }
+        // If any file is not up-to-date, then the whole program is not up-to-date
+        if (program.getSourceFiles().some(sourceFileNotUptoDate)) {
+            return false;
+        }
+        // If any of the missing file paths are now created
+        if (program.getMissingFilePaths().some(fileExists)) {
+            return false;
+        }
+        var currentOptions = program.getCompilerOptions();
+        // If the compilation settings do no match, then the program is not up-to-date
+        if (!ts.compareDataObjects(currentOptions, newOptions)) {
+            return false;
+        }
+        // If everything matches but the text of config file is changed,
+        // error locations can change for program options, so update the program
+        if (currentOptions.configFile && newOptions.configFile) {
+            return currentOptions.configFile.text === newOptions.configFile.text;
+        }
+        return true;
+        function sourceFileNotUptoDate(sourceFile) {
+            return sourceFile.version !== getSourceVersion(sourceFile.path) ||
+                hasInvalidatedResolution(sourceFile.path);
+        }
+    }
+    ts.isProgramUptoDate = isProgramUptoDate;
+    /**
+     * Determined if source file needs to be re-created even if its text hasnt changed
+     */
+    function shouldProgramCreateNewSourceFiles(program, newOptions) {
+        // If any of these options change, we cant reuse old source file even if version match
+        // The change in options like these could result in change in syntax tree change
+        var oldOptions = program && program.getCompilerOptions();
+        return oldOptions && (oldOptions.target !== newOptions.target ||
+            oldOptions.module !== newOptions.module ||
+            oldOptions.moduleResolution !== newOptions.moduleResolution ||
+            oldOptions.noResolve !== newOptions.noResolve ||
+            oldOptions.jsx !== newOptions.jsx ||
+            oldOptions.allowJs !== newOptions.allowJs ||
+            oldOptions.disableSizeLimit !== newOptions.disableSizeLimit ||
+            oldOptions.baseUrl !== newOptions.baseUrl ||
+            !ts.equalOwnProperties(oldOptions.paths, newOptions.paths));
+    }
+    /**
+     * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
+     * that represent a compilation unit.
+     *
+     * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and
+     * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in.
+     *
+     * @param rootNames - A set of root files.
+     * @param options - The compiler options which should be used.
+     * @param host - The host interacts with the underlying file system.
+     * @param oldProgram - Reuses an old program structure.
+     * @returns A 'Program' object.
+     */
+    function createProgram(rootNames, options, host, oldProgram) {
+        var program;
+        var files = [];
+        var commonSourceDirectory;
+        var diagnosticsProducingTypeChecker;
+        var noDiagnosticsTypeChecker;
+        var classifiableNames;
+        var modifiedFilePaths;
+        var cachedSemanticDiagnosticsForFile = {};
+        var cachedDeclarationDiagnosticsForFile = {};
+        var resolvedTypeReferenceDirectives = ts.createMap();
+        var fileProcessingDiagnostics = ts.createDiagnosticCollection();
+        // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
+        // This works as imported modules are discovered recursively in a depth first manner, specifically:
+        // - For each root file, findSourceFile is called.
+        // - This calls processImportedModules for each module imported in the source file.
+        // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
+        // As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
+        // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
+        var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
+        var currentNodeModulesDepth = 0;
+        // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
+        // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
+        var modulesWithElidedImports = ts.createMap();
+        // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
+        var sourceFilesFoundSearchingNodeModules = ts.createMap();
+        ts.performance.mark("beforeProgram");
+        host = host || createCompilerHost(options);
+        var skipDefaultLib = options.noLib;
+        var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); });
+        var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName());
+        var programDiagnostics = ts.createDiagnosticCollection();
+        var currentDirectory = host.getCurrentDirectory();
+        var supportedExtensions = ts.getSupportedExtensions(options);
+        // Map storing if there is emit blocking diagnostics for given input
+        var hasEmitBlockingDiagnostics = ts.createMap();
+        var _compilerOptionsObjectLiteralSyntax;
+        var moduleResolutionCache;
+        var resolveModuleNamesWorker;
+        var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
+        if (host.resolveModuleNames) {
+            resolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(checkAllDefined(moduleNames), containingFile, reusedNames).map(function (resolved) {
+                // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
+                if (!resolved || resolved.extension !== undefined) {
+                    return resolved;
+                }
+                var withExtension = ts.clone(resolved);
+                withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName);
+                return withExtension;
+            }); };
+        }
+        else {
+            moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); });
+            var loader_1 = function (moduleName, containingFile) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule; };
+            resolveModuleNamesWorker = function (moduleNames, containingFile) { return loadWithLocalCache(checkAllDefined(moduleNames), containingFile, loader_1); };
+        }
+        var resolveTypeReferenceDirectiveNamesWorker;
+        if (host.resolveTypeReferenceDirectives) {
+            resolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile) { return host.resolveTypeReferenceDirectives(checkAllDefined(typeDirectiveNames), containingFile); };
+        }
+        else {
+            var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; };
+            resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); };
+        }
+        // Map from a stringified PackageId to the source file with that id.
+        // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile).
+        // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around.
+        var packageIdToSourceFile = ts.createMap();
+        // Maps from a SourceFile's `.path` to the name of the package it was imported with.
+        var sourceFileToPackageName = ts.createMap();
+        // See `sourceFileIsRedirectedTo`.
+        var redirectTargetsSet = ts.createMap();
+        var filesByName = ts.createMap();
+        var missingFilePaths;
+        // stores 'filename -> file association' ignoring case
+        // used to track cases when two file names differ only in casing
+        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined;
+        var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
+        var structuralIsReused = tryReuseStructureFromOldProgram();
+        if (structuralIsReused !== 2 /* Completely */) {
+            ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); });
+            // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
+            var typeReferences = ts.getAutomaticTypeDirectiveNames(options, host);
+            if (typeReferences.length) {
+                // This containingFilename needs to match with the one used in managed-side
+                var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
+                var containingFilename = ts.combinePaths(containingDirectory, "__inferred type names__.ts");
+                var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
+                for (var i = 0; i < typeReferences.length; i++) {
+                    processTypeReferenceDirective(typeReferences[i], resolutions[i]);
+                }
+            }
+            // Do not process the default library if:
+            //  - The '--noLib' flag is used.
+            //  - A 'no-default-lib' reference comment is encountered in
+            //      processing the root files.
+            if (!skipDefaultLib) {
+                // If '--lib' is not specified, include default library file according to '--target'
+                // otherwise, using options specified in '--lib' instead of '--target' default library file
+                if (!options.lib) {
+                    processRootFile(getDefaultLibraryFileName(), /*isDefaultLib*/ true);
+                }
+                else {
+                    ts.forEach(options.lib, function (libFileName) {
+                        processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true);
+                    });
+                }
+            }
+            missingFilePaths = ts.arrayFrom(filesByName.keys(), function (p) { return p; }).filter(function (p) { return !filesByName.get(p); });
+        }
+        ts.Debug.assert(!!missingFilePaths);
+        // unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
+        moduleResolutionCache = undefined;
+        // Release any files we have acquired in the old program but are
+        // not part of the new program.
+        if (oldProgram && host.onReleaseOldSourceFile) {
+            var oldSourceFiles = oldProgram.getSourceFiles();
+            for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) {
+                var oldSourceFile = oldSourceFiles_1[_i];
+                if (!getSourceFile(oldSourceFile.path) || shouldCreateNewSourceFile) {
+                    host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions());
+                }
+            }
+        }
+        // unconditionally set oldProgram to undefined to prevent it from being captured in closure
+        oldProgram = undefined;
+        program = {
+            getRootFileNames: function () { return rootNames; },
+            getSourceFile: getSourceFile,
+            getSourceFileByPath: getSourceFileByPath,
+            getSourceFiles: function () { return files; },
+            getMissingFilePaths: function () { return missingFilePaths; },
+            getCompilerOptions: function () { return options; },
+            getSyntacticDiagnostics: getSyntacticDiagnostics,
+            getOptionsDiagnostics: getOptionsDiagnostics,
+            getGlobalDiagnostics: getGlobalDiagnostics,
+            getSemanticDiagnostics: getSemanticDiagnostics,
+            getDeclarationDiagnostics: getDeclarationDiagnostics,
+            getTypeChecker: getTypeChecker,
+            getClassifiableNames: getClassifiableNames,
+            getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker,
+            getCommonSourceDirectory: getCommonSourceDirectory,
+            emit: emit,
+            getCurrentDirectory: function () { return currentDirectory; },
+            getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); },
+            getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); },
+            getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); },
+            getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); },
+            getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; },
+            getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; },
+            isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
+            isSourceFileDefaultLibrary: isSourceFileDefaultLibrary,
+            dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker,
+            getSourceFileFromReference: getSourceFileFromReference,
+            sourceFileToPackageName: sourceFileToPackageName,
+            redirectTargetsSet: redirectTargetsSet
+        };
+        verifyCompilerOptions();
+        ts.performance.mark("afterProgram");
+        ts.performance.measure("Program", "beforeProgram", "afterProgram");
+        return program;
+        function toPath(fileName) {
+            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+        }
+        function getCommonSourceDirectory() {
+            if (commonSourceDirectory === undefined) {
+                var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary); });
+                if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
+                    // If a rootDir is specified and is valid use it as the commonSourceDirectory
+                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
+                }
+                else {
+                    commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
+                }
+                if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) {
+                    // Make sure directory path ends with directory separator so this string can directly
+                    // used to replace with "" to get the relative path of the source file and the relative path doesn't
+                    // start with / making it rooted path
+                    commonSourceDirectory += ts.directorySeparator;
+                }
+            }
+            return commonSourceDirectory;
+        }
+        function getClassifiableNames() {
+            if (!classifiableNames) {
+                // Initialize a checker so that all our files are bound.
+                getTypeChecker();
+                classifiableNames = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
+                    var sourceFile = files_2[_i];
+                    ts.copyEntries(sourceFile.classifiableNames, classifiableNames);
+                }
+            }
+            return classifiableNames;
+        }
+        function resolveModuleNamesReusingOldState(moduleNames, containingFile, file, oldProgramState) {
+            if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
+                // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
+                // the best we can do is fallback to the default logic.
+                return resolveModuleNamesWorker(moduleNames, containingFile);
+            }
+            var oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
+            if (oldSourceFile !== file && file.resolvedModules) {
+                // `file` was created for the new program.
+                //
+                // We only set `file.resolvedModules` via work from the current function,
+                // so it is defined iff we already called the current function on `file`.
+                // That call happened no later than the creation of the `file` object,
+                // which per above occured during the current program creation.
+                // Since we assume the filesystem does not change during program creation,
+                // it is safe to reuse resolutions from the earlier call.
+                var result_4 = [];
+                for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
+                    var moduleName = moduleNames_1[_i];
+                    var resolvedModule = file.resolvedModules.get(moduleName);
+                    result_4.push(resolvedModule);
+                }
+                return result_4;
+            }
+            // At this point, we know at least one of the following hold:
+            // - file has local declarations for ambient modules
+            // - old program state is available
+            // With this information, we can infer some module resolutions without performing resolution.
+            /** An ordered list of module names for which we cannot recover the resolution. */
+            var unknownModuleNames;
+            /**
+             * The indexing of elements in this list matches that of `moduleNames`.
+             *
+             * Before combining results, result[i] is in one of the following states:
+             * * undefined: needs to be recomputed,
+             * * predictedToResolveToAmbientModuleMarker: known to be an ambient module.
+             * Needs to be reset to undefined before returning,
+             * * ResolvedModuleFull instance: can be reused.
+             */
+            var result;
+            var reusedNames;
+            /** A transient placeholder used to mark predicted resolution in the result list. */
+            var predictedToResolveToAmbientModuleMarker = {};
+            for (var i = 0; i < moduleNames.length; i++) {
+                var moduleName = moduleNames[i];
+                // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
+                if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
+                    var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
+                    if (oldResolvedModule) {
+                        if (ts.isTraceEnabled(options, host)) {
+                            ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
+                        }
+                        (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule;
+                        (reusedNames || (reusedNames = [])).push(moduleName);
+                        continue;
+                    }
+                }
+                // We know moduleName resolves to an ambient module provided that moduleName:
+                // - is in the list of ambient modules locally declared in the current source file.
+                // - resolved to an ambient module in the old program whose declaration is in an unmodified file
+                //   (so the same module declaration will land in the new program)
+                var resolvesToAmbientModuleInNonModifiedFile = false;
+                if (ts.contains(file.ambientModuleNames, moduleName)) {
+                    resolvesToAmbientModuleInNonModifiedFile = true;
+                    if (ts.isTraceEnabled(options, host)) {
+                        ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
+                    }
+                }
+                else {
+                    resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState);
+                }
+                if (resolvesToAmbientModuleInNonModifiedFile) {
+                    (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
+                }
+                else {
+                    // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
+                    (unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
+                }
+            }
+            var resolutions = unknownModuleNames && unknownModuleNames.length
+                ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames)
+                : ts.emptyArray;
+            // Combine results of resolutions and predicted results
+            if (!result) {
+                // There were no unresolved/ambient resolutions.
+                ts.Debug.assert(resolutions.length === moduleNames.length);
+                return resolutions;
+            }
+            var j = 0;
+            for (var i = 0; i < result.length; i++) {
+                if (result[i]) {
+                    // `result[i]` is either a `ResolvedModuleFull` or a marker.
+                    // If it is the former, we can leave it as is.
+                    if (result[i] === predictedToResolveToAmbientModuleMarker) {
+                        result[i] = undefined;
+                    }
+                }
+                else {
+                    result[i] = resolutions[j];
+                    j++;
+                }
+            }
+            ts.Debug.assert(j === resolutions.length);
+            return result;
+            // If we change our policy of rechecking failed lookups on each program create,
+            // we should adjust the value returned here.
+            function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState) {
+                var resolutionToFile = ts.getResolvedModule(oldProgramState.file, moduleName);
+                if (resolutionToFile) {
+                    // module used to be resolved to file - ignore it
+                    return false;
+                }
+                var ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
+                if (!(ambientModule && ambientModule.declarations)) {
+                    return false;
+                }
+                // at least one of declarations should come from non-modified source file
+                var firstUnmodifiedFile = ts.forEach(ambientModule.declarations, function (d) {
+                    var f = ts.getSourceFileOfNode(d);
+                    return !ts.contains(oldProgramState.modifiedFilePaths, f.path) && f;
+                });
+                if (!firstUnmodifiedFile) {
+                    return false;
+                }
+                if (ts.isTraceEnabled(options, host)) {
+                    ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName);
+                }
+                return true;
+            }
+        }
+        function tryReuseStructureFromOldProgram() {
+            if (!oldProgram) {
+                return 0 /* Not */;
+            }
+            // check properties that can affect structure of the program or module resolution strategy
+            // if any of these properties has changed - structure cannot be reused
+            var oldOptions = oldProgram.getCompilerOptions();
+            if (ts.changesAffectModuleResolution(oldOptions, options)) {
+                return oldProgram.structureIsReused = 0 /* Not */;
+            }
+            ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */)));
+            // there is an old program, check if we can reuse its structure
+            var oldRootNames = oldProgram.getRootFileNames();
+            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
+                return oldProgram.structureIsReused = 0 /* Not */;
+            }
+            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
+                return oldProgram.structureIsReused = 0 /* Not */;
+            }
+            // check if program source files has changed in the way that can affect structure of the program
+            var newSourceFiles = [];
+            var filePaths = [];
+            var modifiedSourceFiles = [];
+            oldProgram.structureIsReused = 2 /* Completely */;
+            // If the missing file paths are now present, it can change the progam structure,
+            // and hence cant reuse the structure.
+            // This is same as how we dont reuse the structure if one of the file from old program is now missing
+            if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) {
+                return oldProgram.structureIsReused = 0 /* Not */;
+            }
+            var oldSourceFiles = oldProgram.getSourceFiles();
+            var SeenPackageName;
+            (function (SeenPackageName) {
+                SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists";
+                SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified";
+            })(SeenPackageName || (SeenPackageName = {}));
+            var seenPackageNames = ts.createMap();
+            for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) {
+                var oldSourceFile = oldSourceFiles_2[_i];
+                var newSourceFile = host.getSourceFileByPath
+                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
+                    : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile);
+                if (!newSourceFile) {
+                    return oldProgram.structureIsReused = 0 /* Not */;
+                }
+                ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
+                var fileChanged = void 0;
+                if (oldSourceFile.redirectInfo) {
+                    // We got `newSourceFile` by path, so it is actually for the unredirected file.
+                    // This lets us know if the unredirected file has changed. If it has we should break the redirect.
+                    if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
+                        // Underlying file has changed. Might not redirect anymore. Must rebuild program.
+                        return oldProgram.structureIsReused = 0 /* Not */;
+                    }
+                    fileChanged = false;
+                    newSourceFile = oldSourceFile; // Use the redirect.
+                }
+                else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) {
+                    // If a redirected-to source file changes, the redirect may be broken.
+                    if (newSourceFile !== oldSourceFile) {
+                        return oldProgram.structureIsReused = 0 /* Not */;
+                    }
+                    fileChanged = false;
+                }
+                else {
+                    fileChanged = newSourceFile !== oldSourceFile;
+                }
+                newSourceFile.path = oldSourceFile.path;
+                filePaths.push(newSourceFile.path);
+                var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
+                if (packageName !== undefined) {
+                    // If there are 2 different source files for the same package name and at least one of them changes,
+                    // they might become redirects. So we must rebuild the program.
+                    var prevKind = seenPackageNames.get(packageName);
+                    var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
+                    if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) {
+                        return oldProgram.structureIsReused = 0 /* Not */;
+                    }
+                    seenPackageNames.set(packageName, newKind);
+                }
+                if (fileChanged) {
+                    // The `newSourceFile` object was created for the new program.
+                    if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
+                        // value of no-default-lib has changed
+                        // this will affect if default library is injected into the list of files
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    // check tripleslash references
+                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
+                        // tripleslash references has changed
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    // check imports and module augmentations
+                    collectExternalModuleReferences(newSourceFile);
+                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
+                        // imports has changed
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
+                        // moduleAugmentations has changed
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    if ((oldSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */) !== (newSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */)) {
+                        // dynamicImport has changed
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
+                        // 'types' references has changed
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                    }
+                    // tentatively approve the file
+                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
+                }
+                else if (hasInvalidatedResolution(oldSourceFile.path)) {
+                    // 'module/types' references could have changed
+                    oldProgram.structureIsReused = 1 /* SafeModules */;
+                    // add file to the modified list so that we will resolve it later
+                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
+                }
+                // if file has passed all checks it should be safe to reuse it
+                newSourceFiles.push(newSourceFile);
+            }
+            if (oldProgram.structureIsReused !== 2 /* Completely */) {
+                return oldProgram.structureIsReused;
+            }
+            modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; });
+            // try to verify results of module resolution
+            for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) {
+                var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile;
+                var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
+                if (resolveModuleNamesWorker) {
+                    var moduleNames = getModuleNames(newSourceFile);
+                    var oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths: modifiedFilePaths };
+                    var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
+                    // ensure that module resolution results are still correct
+                    var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
+                    if (resolutionsChanged) {
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                        newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions);
+                    }
+                    else {
+                        newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
+                    }
+                }
+                if (resolveTypeReferenceDirectiveNamesWorker) {
+                    var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (x) { return x.fileName; });
+                    var resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
+                    // ensure that types resolutions are still correct
+                    var resolutionsChanged = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo);
+                    if (resolutionsChanged) {
+                        oldProgram.structureIsReused = 1 /* SafeModules */;
+                        newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions);
+                    }
+                    else {
+                        newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
+                    }
+                }
+            }
+            if (oldProgram.structureIsReused !== 2 /* Completely */) {
+                return oldProgram.structureIsReused;
+            }
+            if (host.hasChangedAutomaticTypeDirectiveNames) {
+                return oldProgram.structureIsReused = 1 /* SafeModules */;
+            }
+            missingFilePaths = oldProgram.getMissingFilePaths();
+            // update fileName -> file mapping
+            for (var i = 0; i < newSourceFiles.length; i++) {
+                filesByName.set(filePaths[i], newSourceFiles[i]);
+                // Set the file as found during node modules search if it was found that way in old progra,
+                if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i]))) {
+                    sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
+                }
+            }
+            files = newSourceFiles;
+            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
+            for (var _c = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _c < modifiedSourceFiles_2.length; _c++) {
+                var modifiedFile = modifiedSourceFiles_2[_c];
+                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
+            }
+            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
+            sourceFileToPackageName = oldProgram.sourceFileToPackageName;
+            redirectTargetsSet = oldProgram.redirectTargetsSet;
+            return oldProgram.structureIsReused = 2 /* Completely */;
+        }
+        function getEmitHost(writeFileCallback) {
+            return {
+                getCanonicalFileName: getCanonicalFileName,
+                getCommonSourceDirectory: program.getCommonSourceDirectory,
+                getCompilerOptions: program.getCompilerOptions,
+                getCurrentDirectory: function () { return currentDirectory; },
+                getNewLine: function () { return host.getNewLine(); },
+                getSourceFile: program.getSourceFile,
+                getSourceFileByPath: program.getSourceFileByPath,
+                getSourceFiles: program.getSourceFiles,
+                isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
+                writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }),
+                isEmitBlocked: isEmitBlocked,
+            };
+        }
+        function isSourceFileFromExternalLibrary(file) {
+            return sourceFilesFoundSearchingNodeModules.get(file.path);
+        }
+        function isSourceFileDefaultLibrary(file) {
+            if (file.hasNoDefaultLib) {
+                return true;
+            }
+            if (!options.noLib) {
+                return false;
+            }
+            // If '--lib' is not specified, include default library file according to '--target'
+            // otherwise, using options specified in '--lib' instead of '--target' default library file
+            if (!options.lib) {
+                return ts.compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
+            }
+            else {
+                return ts.forEach(options.lib, function (libFileName) { return ts.compareStrings(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */; });
+            }
+        }
+        function getDiagnosticsProducingTypeChecker() {
+            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
+        }
+        function dropDiagnosticsProducingTypeChecker() {
+            diagnosticsProducingTypeChecker = undefined;
+        }
+        function getTypeChecker() {
+            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
+        }
+        function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers) {
+            return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers); });
+        }
+        function isEmitBlocked(emitFileName) {
+            return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
+        }
+        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers) {
+            var declarationDiagnostics = [];
+            if (options.noEmit) {
+                return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
+            }
+            // If the noEmitOnError flag is set, then check if we have any errors so far.  If so,
+            // immediately bail out.  Note that we pass 'undefined' for 'sourceFile' so that we
+            // get any preEmit diagnostics, not just the ones
+            if (options.noEmitOnError) {
+                var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
+                if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
+                    declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
+                }
+                if (diagnostics.length > 0 || declarationDiagnostics.length > 0) {
+                    return {
+                        diagnostics: ts.concatenate(diagnostics, declarationDiagnostics),
+                        sourceMaps: undefined,
+                        emittedFiles: undefined,
+                        emitSkipped: true
+                    };
+                }
+            }
+            // Create the emit resolver outside of the "emitTime" tracking code below.  That way
+            // any cost associated with it (like type checking) are appropriate associated with
+            // the type-checking counter.
+            //
+            // If the -out option is specified, we should not pass the source file to getEmitResolver.
+            // This is because in the -out scenario all files need to be emitted, and therefore all
+            // files need to be type checked. And the way to specify that all files need to be type
+            // checked is to not pass the file to getEmitResolver.
+            var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
+            ts.performance.mark("beforeEmit");
+            var transformers = emitOnlyDtsFiles ? [] : ts.getTransformers(options, customTransformers);
+            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, emitOnlyDtsFiles, transformers);
+            ts.performance.mark("afterEmit");
+            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
+            return emitResult;
+        }
+        function getSourceFile(fileName) {
+            return getSourceFileByPath(toPath(fileName));
+        }
+        function getSourceFileByPath(path) {
+            return filesByName.get(path);
+        }
+        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
+            if (sourceFile) {
+                return getDiagnostics(sourceFile, cancellationToken);
+            }
+            return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
+                if (cancellationToken) {
+                    cancellationToken.throwIfCancellationRequested();
+                }
+                return getDiagnostics(sourceFile, cancellationToken);
+            }));
+        }
+        function getSyntacticDiagnostics(sourceFile, cancellationToken) {
+            return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
+        }
+        function getSemanticDiagnostics(sourceFile, cancellationToken) {
+            return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
+        }
+        function getDeclarationDiagnostics(sourceFile, cancellationToken) {
+            var options = program.getCompilerOptions();
+            // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
+            if (!sourceFile || options.out || options.outFile) {
+                return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
+            }
+            else {
+                return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
+            }
+        }
+        function getSyntacticDiagnosticsForFile(sourceFile) {
+            // For JavaScript files, we report semantic errors for using TypeScript-only
+            // constructs from within a JavaScript file as syntactic errors.
+            if (ts.isSourceFileJavaScript(sourceFile)) {
+                if (!sourceFile.additionalSyntacticDiagnostics) {
+                    sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile);
+                    if (ts.isCheckJsEnabledForFile(sourceFile, options)) {
+                        sourceFile.additionalSyntacticDiagnostics = ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.jsDocDiagnostics);
+                    }
+                }
+                return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
+            }
+            return sourceFile.parseDiagnostics;
+        }
+        function runWithCancellationToken(func) {
+            try {
+                return func();
+            }
+            catch (e) {
+                if (e instanceof ts.OperationCanceledException) {
+                    // We were canceled while performing the operation.  Because our type checker
+                    // might be a bad state, we need to throw it away.
+                    //
+                    // Note: we are overly aggressive here.  We do not actually *have* to throw away
+                    // the "noDiagnosticsTypeChecker".  However, for simplicity, i'd like to keep
+                    // the lifetimes of these two TypeCheckers the same.  Also, we generally only
+                    // cancel when the user has made a change anyways.  And, in that case, we (the
+                    // program instance) will get thrown away anyways.  So trying to keep one of
+                    // these type checkers alive doesn't serve much purpose.
+                    noDiagnosticsTypeChecker = undefined;
+                    diagnosticsProducingTypeChecker = undefined;
+                }
+                throw e;
+            }
+        }
+        function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
+            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
+        }
+        function getSemanticDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
+            return runWithCancellationToken(function () {
+                // If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
+                // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
+                // '/// <reference no-default-lib="true"/>' directive.
+                if (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) {
+                    return ts.emptyArray;
+                }
+                var typeChecker = getDiagnosticsProducingTypeChecker();
+                ts.Debug.assert(!!sourceFile.bindDiagnostics);
+                // By default, only type-check .ts, .tsx, and 'External' files (external files are added by plugins)
+                var includeBindAndCheckDiagnostics = sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ ||
+                    sourceFile.scriptKind === 5 /* External */ || ts.isCheckJsEnabledForFile(sourceFile, options);
+                var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray;
+                var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray;
+                var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
+                var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
+                var diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
+                return ts.filter(diagnostics, shouldReportDiagnostic);
+            });
+        }
+        /**
+         * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines
+         */
+        function shouldReportDiagnostic(diagnostic) {
+            var file = diagnostic.file, start = diagnostic.start;
+            if (file) {
+                var lineStarts = ts.getLineStarts(file);
+                var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line;
+                while (line > 0) {
+                    var previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
+                    var result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
+                    if (!result) {
+                        // non-empty line
+                        return true;
+                    }
+                    if (result[3]) {
+                        // @ts-ignore
+                        return false;
+                    }
+                    line--;
+                }
+            }
+            return true;
+        }
+        function getJavaScriptSyntacticDiagnosticsForFile(sourceFile) {
+            return runWithCancellationToken(function () {
+                var diagnostics = [];
+                var parent = sourceFile;
+                walk(sourceFile);
+                return diagnostics;
+                function walk(node) {
+                    // Return directly from the case if the given node doesnt want to visit each child
+                    // Otherwise break to visit each child
+                    switch (parent.kind) {
+                        case 146 /* Parameter */:
+                        case 149 /* PropertyDeclaration */:
+                            if (parent.questionToken === node) {
+                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
+                                return;
+                            }
+                        // falls through
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 152 /* Constructor */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                        case 186 /* FunctionExpression */:
+                        case 228 /* FunctionDeclaration */:
+                        case 187 /* ArrowFunction */:
+                        case 226 /* VariableDeclaration */:
+                            // type annotation
+                            if (parent.type === node) {
+                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.types_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                    }
+                    switch (node.kind) {
+                        case 237 /* ImportEqualsDeclaration */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 243 /* ExportAssignment */:
+                            if (node.isExportEquals) {
+                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                            break;
+                        case 259 /* HeritageClause */:
+                            var heritageClause = node;
+                            if (heritageClause.token === 108 /* ImplementsKeyword */) {
+                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                            break;
+                        case 230 /* InterfaceDeclaration */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 233 /* ModuleDeclaration */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 231 /* TypeAliasDeclaration */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 232 /* EnumDeclaration */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 203 /* NonNullExpression */:
+                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 202 /* AsExpression */:
+                            diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
+                            return;
+                        case 184 /* TypeAssertionExpression */:
+                            ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
+                    }
+                    var prevParent = parent;
+                    parent = node;
+                    ts.forEachChild(node, walk, walkArray);
+                    parent = prevParent;
+                }
+                function walkArray(nodes) {
+                    if (parent.decorators === nodes && !options.experimentalDecorators) {
+                        diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning));
+                    }
+                    switch (parent.kind) {
+                        case 229 /* ClassDeclaration */:
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 152 /* Constructor */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                        case 186 /* FunctionExpression */:
+                        case 228 /* FunctionDeclaration */:
+                        case 187 /* ArrowFunction */:
+                            // Check type parameters
+                            if (nodes === parent.typeParameters) {
+                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                        // falls through
+                        case 208 /* VariableStatement */:
+                            // Check modifiers
+                            if (nodes === parent.modifiers) {
+                                return checkModifiers(nodes, parent.kind === 208 /* VariableStatement */);
+                            }
+                            break;
+                        case 149 /* PropertyDeclaration */:
+                            // Check modifiers of property declaration
+                            if (nodes === parent.modifiers) {
+                                for (var _i = 0, _a = nodes; _i < _a.length; _i++) {
+                                    var modifier = _a[_i];
+                                    if (modifier.kind !== 115 /* StaticKeyword */) {
+                                        diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
+                                    }
+                                }
+                                return;
+                            }
+                            break;
+                        case 146 /* Parameter */:
+                            // Check modifiers of parameter declaration
+                            if (nodes === parent.modifiers) {
+                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                            break;
+                        case 181 /* CallExpression */:
+                        case 182 /* NewExpression */:
+                        case 201 /* ExpressionWithTypeArguments */:
+                            // Check type arguments
+                            if (nodes === parent.typeArguments) {
+                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
+                                return;
+                            }
+                            break;
+                    }
+                    for (var _b = 0, nodes_8 = nodes; _b < nodes_8.length; _b++) {
+                        var node = nodes_8[_b];
+                        walk(node);
+                    }
+                }
+                function checkModifiers(modifiers, isConstValid) {
+                    for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
+                        var modifier = modifiers_1[_i];
+                        switch (modifier.kind) {
+                            case 76 /* ConstKeyword */:
+                                if (isConstValid) {
+                                    continue;
+                                }
+                            // to report error,
+                            // falls through
+                            case 114 /* PublicKeyword */:
+                            case 112 /* PrivateKeyword */:
+                            case 113 /* ProtectedKeyword */:
+                            case 131 /* ReadonlyKeyword */:
+                            case 124 /* DeclareKeyword */:
+                            case 117 /* AbstractKeyword */:
+                                diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
+                                break;
+                            // These are all legal modifiers.
+                            case 115 /* StaticKeyword */:
+                            case 84 /* ExportKeyword */:
+                            case 79 /* DefaultKeyword */:
+                        }
+                    }
+                }
+                function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) {
+                    var start = nodes.pos;
+                    return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
+                }
+                // Since these are syntactic diagnostics, parent might not have been set
+                // this means the sourceFile cannot be infered from the node
+                function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
+                    return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
+                }
+            });
+        }
+        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
+            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
+        }
+        function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
+            return runWithCancellationToken(function () {
+                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
+                // Don't actually write any files since we're just getting diagnostics.
+                return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile);
+            });
+        }
+        function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
+            var cachedResult = sourceFile
+                ? cache.perFile && cache.perFile.get(sourceFile.path)
+                : cache.allDiagnostics;
+            if (cachedResult) {
+                return cachedResult;
+            }
+            var result = getDiagnostics(sourceFile, cancellationToken) || ts.emptyArray;
+            if (sourceFile) {
+                if (!cache.perFile) {
+                    cache.perFile = ts.createMap();
+                }
+                cache.perFile.set(sourceFile.path, result);
+            }
+            else {
+                cache.allDiagnostics = result;
+            }
+            return result;
+        }
+        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
+            return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
+        }
+        function getOptionsDiagnostics() {
+            return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : [])));
+        }
+        function getGlobalDiagnostics() {
+            return ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
+        }
+        function processRootFile(fileName, isDefaultLib) {
+            processSourceFile(ts.normalizePath(fileName), isDefaultLib, /*packageId*/ undefined);
+        }
+        function fileReferenceIsEqualTo(a, b) {
+            return a.fileName === b.fileName;
+        }
+        function moduleNameIsEqualTo(a, b) {
+            return a.kind === 9 /* StringLiteral */
+                ? b.kind === 9 /* StringLiteral */ && a.text === b.text
+                : b.kind === 71 /* Identifier */ && a.escapedText === b.escapedText;
+        }
+        function collectExternalModuleReferences(file) {
+            if (file.imports) {
+                return;
+            }
+            var isJavaScriptFile = ts.isSourceFileJavaScript(file);
+            var isExternalModuleFile = ts.isExternalModule(file);
+            // file.imports may not be undefined if there exists dynamic import
+            var imports;
+            var moduleAugmentations;
+            var ambientModules;
+            // If we are importing helpers, we need to add a synthetic reference to resolve the
+            // helpers library.
+            if (options.importHelpers
+                && (options.isolatedModules || isExternalModuleFile)
+                && !file.isDeclarationFile) {
+                // synthesize 'import "tslib"' declaration
+                var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText);
+                var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined);
+                externalHelpersModuleReference.parent = importDecl;
+                importDecl.parent = file;
+                imports = [externalHelpersModuleReference];
+            }
+            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
+                var node = _a[_i];
+                collectModuleReferences(node, /*inAmbientModule*/ false);
+                if ((file.flags & 524288 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) {
+                    collectDynamicImportOrRequireCalls(node);
+                }
+            }
+            file.imports = imports || ts.emptyArray;
+            file.moduleAugmentations = moduleAugmentations || ts.emptyArray;
+            file.ambientModuleNames = ambientModules || ts.emptyArray;
+            return;
+            function collectModuleReferences(node, inAmbientModule) {
+                switch (node.kind) {
+                    case 238 /* ImportDeclaration */:
+                    case 237 /* ImportEqualsDeclaration */:
+                    case 244 /* ExportDeclaration */:
+                        var moduleNameExpr = ts.getExternalModuleName(node);
+                        if (!moduleNameExpr || !ts.isStringLiteral(moduleNameExpr)) {
+                            break;
+                        }
+                        if (!moduleNameExpr.text) {
+                            break;
+                        }
+                        // TypeScript 1.0 spec (April 2014): 12.1.6
+                        // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
+                        // only through top - level external module names. Relative external module names are not permitted.
+                        if (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
+                            (imports || (imports = [])).push(moduleNameExpr);
+                        }
+                        break;
+                    case 233 /* ModuleDeclaration */:
+                        if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) {
+                            var moduleName = node.name;
+                            var nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
+                            // Ambient module declarations can be interpreted as augmentations for some existing external modules.
+                            // This will happen in two cases:
+                            // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
+                            // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
+                            //   immediately nested in top level ambient module declaration .
+                            if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) {
+                                (moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
+                            }
+                            else if (!inAmbientModule) {
+                                if (file.isDeclarationFile) {
+                                    // for global .d.ts files record name of ambient module
+                                    (ambientModules || (ambientModules = [])).push(nameText);
+                                }
+                                // An AmbientExternalModuleDeclaration declares an external module.
+                                // This type of declaration is permitted only in the global module.
+                                // The StringLiteral must specify a top - level external module name.
+                                // Relative external module names are not permitted
+                                // NOTE: body of ambient module is always a module block, if it exists
+                                var body = node.body;
+                                if (body) {
+                                    for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
+                                        var statement = _a[_i];
+                                        collectModuleReferences(statement, /*inAmbientModule*/ true);
+                                    }
+                                }
+                            }
+                        }
+                }
+            }
+            function collectDynamicImportOrRequireCalls(node) {
+                if (ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
+                    (imports || (imports = [])).push(node.arguments[0]);
+                }
+                else if (ts.isImportCall(node) && node.arguments.length === 1 && node.arguments[0].kind === 9 /* StringLiteral */) {
+                    (imports || (imports = [])).push(node.arguments[0]);
+                }
+                else {
+                    ts.forEachChild(node, collectDynamicImportOrRequireCalls);
+                }
+            }
+        }
+        /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
+        function getSourceFileFromReference(referencingFile, ref) {
+            return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)); });
+        }
+        function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) {
+            if (ts.hasExtension(fileName)) {
+                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensions, function (extension) { return ts.fileExtensionIs(host.getCanonicalFileName(fileName), extension); })) {
+                    if (fail)
+                        fail(ts.Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
+                    return undefined;
+                }
+                var sourceFile = getSourceFile(fileName);
+                if (fail) {
+                    if (!sourceFile) {
+                        fail(ts.Diagnostics.File_0_not_found, fileName);
+                    }
+                    else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
+                        fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself);
+                    }
+                }
+                return sourceFile;
+            }
+            else {
+                var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
+                if (sourceFileNoExtension)
+                    return sourceFileNoExtension;
+                if (fail && options.allowNonTsExtensions) {
+                    fail(ts.Diagnostics.File_0_not_found, fileName);
+                    return undefined;
+                }
+                var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); });
+                if (fail && !sourceFileWithAddedExtension)
+                    fail(ts.Diagnostics.File_0_not_found, fileName + ".ts" /* Ts */);
+                return sourceFileWithAddedExtension;
+            }
+        }
+        /** This has side effects through `findSourceFile`. */
+        function processSourceFile(fileName, isDefaultLib, packageId, refFile, refPos, refEnd) {
+            getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId); }, function (diagnostic) {
+                var args = [];
+                for (var _i = 1; _i < arguments.length; _i++) {
+                    args[_i - 1] = arguments[_i];
+                }
+                fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
+                    ? ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, diagnostic].concat(args)) : ts.createCompilerDiagnostic.apply(void 0, [diagnostic].concat(args)));
+            }, refFile);
+        }
+        function reportFileNamesDifferOnlyInCasingError(fileName, existingFileName, refFile, refPos, refEnd) {
+            if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
+                fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
+            }
+            else {
+                fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
+            }
+        }
+        function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) {
+            var redirect = Object.create(redirectTarget);
+            redirect.fileName = fileName;
+            redirect.path = path;
+            redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected };
+            Object.defineProperties(redirect, {
+                id: {
+                    get: function () { return this.redirectInfo.redirectTarget.id; },
+                    set: function (value) { this.redirectInfo.redirectTarget.id = value; },
+                },
+                symbol: {
+                    get: function () { return this.redirectInfo.redirectTarget.symbol; },
+                    set: function (value) { this.redirectInfo.redirectTarget.symbol = value; },
+                },
+            });
+            return redirect;
+        }
+        // Get source file from normalized fileName
+        function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) {
+            if (filesByName.has(path)) {
+                var file_1 = filesByName.get(path);
+                // try to check if we've already seen this file but with a different casing in path
+                // NOTE: this only makes sense for case-insensitive file systems
+                if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) {
+                    reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd);
+                }
+                // If the file was previously found via a node_modules search, but is now being processed as a root file,
+                // then everything it sucks in may also be marked incorrectly, and needs to be checked again.
+                if (file_1 && sourceFilesFoundSearchingNodeModules.get(file_1.path) && currentNodeModulesDepth === 0) {
+                    sourceFilesFoundSearchingNodeModules.set(file_1.path, false);
+                    if (!options.noResolve) {
+                        processReferencedFiles(file_1, isDefaultLib);
+                        processTypeReferenceDirectives(file_1);
+                    }
+                    modulesWithElidedImports.set(file_1.path, false);
+                    processImportedModules(file_1);
+                }
+                else if (file_1 && modulesWithElidedImports.get(file_1.path)) {
+                    if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
+                        modulesWithElidedImports.set(file_1.path, false);
+                        processImportedModules(file_1);
+                    }
+                }
+                return file_1;
+            }
+            // We haven't looked for this file, do so now and cache result
+            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) {
+                if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
+                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
+                }
+                else {
+                    fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
+                }
+            }, shouldCreateNewSourceFile);
+            if (packageId) {
+                var packageIdKey = packageId.name + "/" + packageId.subModuleName + "@" + packageId.version;
+                var fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
+                if (fileFromPackageId) {
+                    // Some other SourceFile already exists with this package name and version.
+                    // Instead of creating a duplicate, just redirect to the existing one.
+                    var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path);
+                    redirectTargetsSet.set(fileFromPackageId.path, true);
+                    filesByName.set(path, dupFile);
+                    sourceFileToPackageName.set(path, packageId.name);
+                    files.push(dupFile);
+                    return dupFile;
+                }
+                else if (file) {
+                    // This is the first source file to have this packageId.
+                    packageIdToSourceFile.set(packageIdKey, file);
+                    sourceFileToPackageName.set(path, packageId.name);
+                }
+            }
+            filesByName.set(path, file);
+            if (file) {
+                sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
+                file.path = path;
+                if (host.useCaseSensitiveFileNames()) {
+                    var pathLowerCase = path.toLowerCase();
+                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
+                    var existingFile = filesByNameIgnoreCase.get(pathLowerCase);
+                    if (existingFile) {
+                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
+                    }
+                    else {
+                        filesByNameIgnoreCase.set(pathLowerCase, file);
+                    }
+                }
+                skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
+                if (!options.noResolve) {
+                    processReferencedFiles(file, isDefaultLib);
+                    processTypeReferenceDirectives(file);
+                }
+                // always process imported modules to record module name resolutions
+                processImportedModules(file);
+                if (isDefaultLib) {
+                    files.unshift(file);
+                }
+                else {
+                    files.push(file);
+                }
+            }
+            return file;
+        }
+        function processReferencedFiles(file, isDefaultLib) {
+            ts.forEach(file.referencedFiles, function (ref) {
+                var referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
+                processSourceFile(referencedFileName, isDefaultLib, /*packageId*/ undefined, file, ref.pos, ref.end);
+            });
+        }
+        function processTypeReferenceDirectives(file) {
+            // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
+            var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ref.fileName.toLocaleLowerCase(); });
+            var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
+            for (var i = 0; i < typeDirectives.length; i++) {
+                var ref = file.typeReferenceDirectives[i];
+                var resolvedTypeReferenceDirective = resolutions[i];
+                // store resolved type directive on the file
+                var fileName = ref.fileName.toLocaleLowerCase();
+                ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
+                processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end);
+            }
+        }
+        function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile, refPos, refEnd) {
+            // If we already found this library as a primary reference - nothing to do
+            var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
+            if (previousResolution && previousResolution.primary) {
+                return;
+            }
+            var saveResolution = true;
+            if (resolvedTypeReferenceDirective) {
+                if (resolvedTypeReferenceDirective.primary) {
+                    // resolved from the primary path
+                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
+                }
+                else {
+                    // If we already resolved to this file, it must have been a secondary reference. Check file contents
+                    // for sameness and possibly issue an error
+                    if (previousResolution) {
+                        // Don't bother reading the file again if it's the same file.
+                        if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
+                            var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
+                            if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
+                                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName));
+                            }
+                        }
+                        // don't overwrite previous resolution result
+                        saveResolution = false;
+                    }
+                    else {
+                        // First resolution of this library
+                        processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
+                    }
+                }
+            }
+            else {
+                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
+            }
+            if (saveResolution) {
+                resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
+            }
+        }
+        function createDiagnostic(refFile, refPos, refEnd, message) {
+            var args = [];
+            for (var _i = 4; _i < arguments.length; _i++) {
+                args[_i - 4] = arguments[_i];
+            }
+            if (refFile === undefined || refPos === undefined || refEnd === undefined) {
+                return ts.createCompilerDiagnostic.apply(void 0, [message].concat(args));
+            }
+            else {
+                return ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, message].concat(args));
+            }
+        }
+        function getCanonicalFileName(fileName) {
+            return host.getCanonicalFileName(fileName);
+        }
+        function processImportedModules(file) {
+            collectExternalModuleReferences(file);
+            if (file.imports.length || file.moduleAugmentations.length) {
+                // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
+                var moduleNames = getModuleNames(file);
+                var oldProgramState = { program: oldProgram, file: file, modifiedFilePaths: modifiedFilePaths };
+                var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
+                ts.Debug.assert(resolutions.length === moduleNames.length);
+                for (var i = 0; i < moduleNames.length; i++) {
+                    var resolution = resolutions[i];
+                    ts.setResolvedModule(file, moduleNames[i], resolution);
+                    if (!resolution) {
+                        continue;
+                    }
+                    var isFromNodeModulesSearch = resolution.isExternalLibraryImport;
+                    var isJsFile = !ts.extensionIsTypeScript(resolution.extension);
+                    var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
+                    var resolvedFileName = resolution.resolvedFileName;
+                    if (isFromNodeModulesSearch) {
+                        currentNodeModulesDepth++;
+                    }
+                    // add file to program only if:
+                    // - resolution was successful
+                    // - noResolve is falsy
+                    // - module name comes from the list of imports
+                    // - it's not a top level JavaScript module that exceeded the search max
+                    var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
+                    // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
+                    // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
+                    var shouldAddFile = resolvedFileName
+                        && !getResolutionDiagnostic(options, resolution)
+                        && !options.noResolve
+                        && i < file.imports.length
+                        && !elideImport
+                        && !(isJsFile && !options.allowJs);
+                    if (elideImport) {
+                        modulesWithElidedImports.set(file.path, true);
+                    }
+                    else if (shouldAddFile) {
+                        var path = toPath(resolvedFileName);
+                        var pos = ts.skipTrivia(file.text, file.imports[i].pos);
+                        findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId);
+                    }
+                    if (isFromNodeModulesSearch) {
+                        currentNodeModulesDepth--;
+                    }
+                }
+            }
+            else {
+                // no imports - drop cached module resolutions
+                file.resolvedModules = undefined;
+            }
+        }
+        function computeCommonSourceDirectory(sourceFiles) {
+            var fileNames = [];
+            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
+                var file = sourceFiles_2[_i];
+                if (!file.isDeclarationFile) {
+                    fileNames.push(file.fileName);
+                }
+            }
+            return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
+        }
+        function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
+            var allFilesBelongToPath = true;
+            if (sourceFiles) {
+                var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory));
+                for (var _i = 0, sourceFiles_3 = sourceFiles; _i < sourceFiles_3.length; _i++) {
+                    var sourceFile = sourceFiles_3[_i];
+                    if (!sourceFile.isDeclarationFile) {
+                        var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
+                        if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
+                            programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
+                            allFilesBelongToPath = false;
+                        }
+                    }
+                }
+            }
+            return allFilesBelongToPath;
+        }
+        function verifyCompilerOptions() {
+            if (options.isolatedModules) {
+                if (options.declaration) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
+                }
+                if (options.noEmitOnError) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules");
+                }
+                if (options.out) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
+                }
+                if (options.outFile) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
+                }
+            }
+            if (options.inlineSourceMap) {
+                if (options.sourceMap) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
+                }
+                if (options.mapRoot) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
+                }
+            }
+            if (options.paths && options.baseUrl === undefined) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
+            }
+            if (options.paths) {
+                for (var key in options.paths) {
+                    if (!ts.hasProperty(options.paths, key)) {
+                        continue;
+                    }
+                    if (!ts.hasZeroOrOneAsteriskCharacter(key)) {
+                        createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
+                    }
+                    if (ts.isArray(options.paths[key])) {
+                        var len = options.paths[key].length;
+                        if (len === 0) {
+                            createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
+                        }
+                        for (var i = 0; i < len; i++) {
+                            var subst = options.paths[key][i];
+                            var typeOfSubst = typeof subst;
+                            if (typeOfSubst === "string") {
+                                if (!ts.hasZeroOrOneAsteriskCharacter(subst)) {
+                                    createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key);
+                                }
+                            }
+                            else {
+                                createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
+                            }
+                        }
+                    }
+                    else {
+                        createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
+                    }
+                }
+            }
+            if (!options.sourceMap && !options.inlineSourceMap) {
+                if (options.inlineSources) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
+                }
+                if (options.sourceRoot) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
+                }
+            }
+            if (options.out && options.outFile) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
+            }
+            if (options.mapRoot && !options.sourceMap) {
+                // Error to specify --mapRoot without --sourcemap
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap");
+            }
+            if (options.declarationDir) {
+                if (!options.declaration) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
+                }
+                if (options.out || options.outFile) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
+                }
+            }
+            if (options.lib && options.noLib) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
+            }
+            if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
+            }
+            var languageVersion = options.target || 0 /* ES3 */;
+            var outFile = options.outFile || options.out;
+            var firstNonAmbientExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; });
+            if (options.isolatedModules) {
+                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
+                }
+                var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; });
+                if (firstNonExternalModuleSourceFile) {
+                    var span_7 = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
+                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span_7.start, span_7.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
+                }
+            }
+            else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) {
+                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
+                var span_8 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
+                programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_8.start, span_8.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
+            }
+            // Cannot specify module gen that isn't amd or system with --out
+            if (outFile) {
+                if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
+                }
+                else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
+                    var span_9 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
+                    programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_9.start, span_9.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
+                }
+            }
+            // there has to be common source directory if user specified --outdir || --sourceRoot
+            // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
+            if (options.outDir || // there is --outDir specified
+                options.sourceRoot || // there is --sourceRoot specified
+                options.mapRoot) {
+                // Precalculate and cache the common source directory
+                var dir = getCommonSourceDirectory();
+                // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
+                if (options.outDir && dir === "" && ts.forEach(files, function (file) { return ts.getRootLength(file.fileName) > 1; })) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
+                }
+            }
+            if (!options.noEmit && options.allowJs && options.declaration) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration");
+            }
+            if (options.checkJs && !options.allowJs) {
+                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
+            }
+            if (options.emitDecoratorMetadata &&
+                !options.experimentalDecorators) {
+                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
+            }
+            if (options.jsxFactory) {
+                if (options.reactNamespace) {
+                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
+                }
+                if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
+                    createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
+                }
+            }
+            else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) {
+                createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
+            }
+            // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
+            if (!options.noEmit && !options.suppressOutputPathCheck) {
+                var emitHost = getEmitHost();
+                var emitFilesSeen_1 = ts.createMap();
+                ts.forEachEmittedFile(emitHost, function (emitFileNames) {
+                    verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1);
+                    verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1);
+                });
+            }
+            // Verify that all the emit files are unique and don't overwrite input files
+            function verifyEmitFilePath(emitFileName, emitFilesSeen) {
+                if (emitFileName) {
+                    var emitFilePath = toPath(emitFileName);
+                    // Report error if the output overwrites input file
+                    if (filesByName.has(emitFilePath)) {
+                        var chain_1;
+                        if (!options.configFilePath) {
+                            // The program is from either an inferred project or an external project
+                            chain_1 = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
+                        }
+                        chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
+                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain_1));
+                    }
+                    var emitFileKey = !host.useCaseSensitiveFileNames() ? emitFilePath.toLocaleLowerCase() : emitFilePath;
+                    // Report error if multiple files write into same file
+                    if (emitFilesSeen.has(emitFileKey)) {
+                        // Already seen the same emit file - report error
+                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
+                    }
+                    else {
+                        emitFilesSeen.set(emitFileKey, true);
+                    }
+                }
+            }
+        }
+        function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) {
+            var needCompilerDiagnostic = true;
+            var pathsSyntax = getOptionPathsSyntax();
+            for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) {
+                var pathProp = pathsSyntax_1[_i];
+                if (ts.isObjectLiteralExpression(pathProp.initializer)) {
+                    for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) {
+                        var keyProps = _b[_a];
+                        if (ts.isArrayLiteralExpression(keyProps.initializer) &&
+                            keyProps.initializer.elements.length > valueIndex) {
+                            programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2));
+                            needCompilerDiagnostic = false;
+                        }
+                    }
+                }
+            }
+            if (needCompilerDiagnostic) {
+                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
+            }
+        }
+        function createDiagnosticForOptionPaths(onKey, key, message, arg0) {
+            var needCompilerDiagnostic = true;
+            var pathsSyntax = getOptionPathsSyntax();
+            for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) {
+                var pathProp = pathsSyntax_2[_i];
+                if (ts.isObjectLiteralExpression(pathProp.initializer) &&
+                    createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) {
+                    needCompilerDiagnostic = false;
+                }
+            }
+            if (needCompilerDiagnostic) {
+                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0));
+            }
+        }
+        function getOptionPathsSyntax() {
+            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
+            if (compilerOptionsObjectLiteralSyntax) {
+                return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths");
+            }
+            return ts.emptyArray;
+        }
+        function createDiagnosticForOptionName(message, option1, option2) {
+            createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2);
+        }
+        function createOptionValueDiagnostic(option1, message, arg0) {
+            createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
+        }
+        function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1) {
+            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
+            var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
+                !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1);
+            if (needCompilerDiagnostic) {
+                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1));
+            }
+        }
+        function getCompilerOptionsObjectLiteralSyntax() {
+            if (_compilerOptionsObjectLiteralSyntax === undefined) {
+                _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
+                if (options.configFile && options.configFile.jsonObject) {
+                    for (var _i = 0, _a = ts.getPropertyAssignment(options.configFile.jsonObject, "compilerOptions"); _i < _a.length; _i++) {
+                        var prop = _a[_i];
+                        if (ts.isObjectLiteralExpression(prop.initializer)) {
+                            _compilerOptionsObjectLiteralSyntax = prop.initializer;
+                            break;
+                        }
+                    }
+                }
+            }
+            return _compilerOptionsObjectLiteralSyntax;
+        }
+        function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1) {
+            var props = ts.getPropertyAssignment(objectLiteral, key1, key2);
+            for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
+                var prop = props_2[_i];
+                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1));
+            }
+            return !!props.length;
+        }
+        function blockEmittingOfFile(emitFileName, diag) {
+            hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
+            programDiagnostics.add(diag);
+        }
+    }
+    ts.createProgram = createProgram;
+    /* @internal */
+    /**
+     * Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
+     * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
+     * This returns a diagnostic even if the module will be an untyped module.
+     */
+    function getResolutionDiagnostic(options, _a) {
+        var extension = _a.extension;
+        switch (extension) {
+            case ".ts" /* Ts */:
+            case ".d.ts" /* Dts */:
+                // These are always allowed.
+                return undefined;
+            case ".tsx" /* Tsx */:
+                return needJsx();
+            case ".jsx" /* Jsx */:
+                return needJsx() || needAllowJs();
+            case ".js" /* Js */:
+                return needAllowJs();
+        }
+        function needJsx() {
+            return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
+        }
+        function needAllowJs() {
+            return options.allowJs || !options.noImplicitAny ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
+        }
+    }
+    ts.getResolutionDiagnostic = getResolutionDiagnostic;
+    function checkAllDefined(names) {
+        ts.Debug.assert(names.every(function (name) { return name !== undefined; }), "A name is undefined.", function () { return JSON.stringify(names); });
+        return names;
+    }
+    function getModuleNames(_a) {
+        var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations;
+        var res = imports.map(function (i) { return i.text; });
+        for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) {
+            var aug = moduleAugmentations_1[_i];
+            if (aug.kind === 9 /* StringLiteral */) {
+                res.push(aug.text);
+            }
+            // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
+        }
+        return res;
+    }
+})(ts || (ts = {}));
+/// <reference path="sys.ts"/>
+/// <reference path="types.ts"/>
+/// <reference path="core.ts"/>
+/// <reference path="diagnosticInformationMap.generated.ts"/>
+/// <reference path="parser.ts"/>
+var ts;
+(function (ts) {
+    /* @internal */
+    ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" };
+    /* @internal */
+    ts.optionDeclarations = [
+        // CommandLine only options
+        {
+            name: "help",
+            shortName: "h",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Print_this_message,
+        },
+        {
+            name: "help",
+            shortName: "?",
+            type: "boolean"
+        },
+        {
+            name: "all",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Show_all_compiler_options,
+        },
+        {
+            name: "version",
+            shortName: "v",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Print_the_compiler_s_version,
+        },
+        {
+            name: "init",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file,
+        },
+        {
+            name: "project",
+            shortName: "p",
+            type: "string",
+            isFilePath: true,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
+            description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json,
+        },
+        {
+            name: "pretty",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
+        },
+        {
+            name: "watch",
+            shortName: "w",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Command_line_Options,
+            description: ts.Diagnostics.Watch_input_files,
+        },
+        // Basic
+        {
+            name: "target",
+            shortName: "t",
+            type: ts.createMapFromTemplate({
+                "es3": 0 /* ES3 */,
+                "es5": 1 /* ES5 */,
+                "es6": 2 /* ES2015 */,
+                "es2015": 2 /* ES2015 */,
+                "es2016": 3 /* ES2016 */,
+                "es2017": 4 /* ES2017 */,
+                "esnext": 5 /* ESNext */,
+            }),
+            paramType: ts.Diagnostics.VERSION,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT,
+        },
+        {
+            name: "module",
+            shortName: "m",
+            type: ts.createMapFromTemplate({
+                "none": ts.ModuleKind.None,
+                "commonjs": ts.ModuleKind.CommonJS,
+                "amd": ts.ModuleKind.AMD,
+                "system": ts.ModuleKind.System,
+                "umd": ts.ModuleKind.UMD,
+                "es6": ts.ModuleKind.ES2015,
+                "es2015": ts.ModuleKind.ES2015,
+                "esnext": ts.ModuleKind.ESNext
+            }),
+            paramType: ts.Diagnostics.KIND,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext,
+        },
+        {
+            name: "lib",
+            type: "list",
+            element: {
+                name: "lib",
+                type: ts.createMapFromTemplate({
+                    // JavaScript only
+                    "es5": "lib.es5.d.ts",
+                    "es6": "lib.es2015.d.ts",
+                    "es2015": "lib.es2015.d.ts",
+                    "es7": "lib.es2016.d.ts",
+                    "es2016": "lib.es2016.d.ts",
+                    "es2017": "lib.es2017.d.ts",
+                    "esnext": "lib.esnext.d.ts",
+                    // Host only
+                    "dom": "lib.dom.d.ts",
+                    "dom.iterable": "lib.dom.iterable.d.ts",
+                    "webworker": "lib.webworker.d.ts",
+                    "scripthost": "lib.scripthost.d.ts",
+                    // ES2015 Or ESNext By-feature options
+                    "es2015.core": "lib.es2015.core.d.ts",
+                    "es2015.collection": "lib.es2015.collection.d.ts",
+                    "es2015.generator": "lib.es2015.generator.d.ts",
+                    "es2015.iterable": "lib.es2015.iterable.d.ts",
+                    "es2015.promise": "lib.es2015.promise.d.ts",
+                    "es2015.proxy": "lib.es2015.proxy.d.ts",
+                    "es2015.reflect": "lib.es2015.reflect.d.ts",
+                    "es2015.symbol": "lib.es2015.symbol.d.ts",
+                    "es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts",
+                    "es2016.array.include": "lib.es2016.array.include.d.ts",
+                    "es2017.object": "lib.es2017.object.d.ts",
+                    "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
+                    "es2017.string": "lib.es2017.string.d.ts",
+                    "es2017.intl": "lib.es2017.intl.d.ts",
+                    "esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
+                }),
+            },
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
+        },
+        {
+            name: "allowJs",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
+        },
+        {
+            name: "checkJs",
+            type: "boolean",
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Report_errors_in_js_files
+        },
+        {
+            name: "jsx",
+            type: ts.createMapFromTemplate({
+                "preserve": 1 /* Preserve */,
+                "react-native": 3 /* ReactNative */,
+                "react": 2 /* React */
+            }),
+            paramType: ts.Diagnostics.KIND,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
+        },
+        {
+            name: "declaration",
+            shortName: "d",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Generates_corresponding_d_ts_file,
+        },
+        {
+            name: "sourceMap",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Generates_corresponding_map_file,
+        },
+        {
+            name: "outFile",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.FILE,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
+        },
+        {
+            name: "outDir",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.DIRECTORY,
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
+        },
+        {
+            name: "rootDir",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.LOCATION,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
+        },
+        {
+            name: "removeComments",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Do_not_emit_comments_to_output,
+        },
+        {
+            name: "noEmit",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Do_not_emit_outputs,
+        },
+        {
+            name: "importHelpers",
+            type: "boolean",
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Import_emit_helpers_from_tslib
+        },
+        {
+            name: "downlevelIteration",
+            type: "boolean",
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
+        },
+        {
+            name: "isolatedModules",
+            type: "boolean",
+            category: ts.Diagnostics.Basic_Options,
+            description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule
+        },
+        // Strict Type Checks
+        {
+            name: "strict",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Enable_all_strict_type_checking_options
+        },
+        {
+            name: "noImplicitAny",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type,
+        },
+        {
+            name: "strictNullChecks",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Enable_strict_null_checks
+        },
+        {
+            name: "strictFunctionTypes",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Enable_strict_checking_of_function_types
+        },
+        {
+            name: "noImplicitThis",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
+        },
+        {
+            name: "alwaysStrict",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Strict_Type_Checking_Options,
+            description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
+        },
+        // Additional Checks
+        {
+            name: "noUnusedLocals",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Additional_Checks,
+            description: ts.Diagnostics.Report_errors_on_unused_locals,
+        },
+        {
+            name: "noUnusedParameters",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Additional_Checks,
+            description: ts.Diagnostics.Report_errors_on_unused_parameters,
+        },
+        {
+            name: "noImplicitReturns",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Additional_Checks,
+            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
+        },
+        {
+            name: "noFallthroughCasesInSwitch",
+            type: "boolean",
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Additional_Checks,
+            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
+        },
+        // Module Resolution
+        {
+            name: "moduleResolution",
+            type: ts.createMapFromTemplate({
+                "node": ts.ModuleResolutionKind.NodeJs,
+                "classic": ts.ModuleResolutionKind.Classic,
+            }),
+            paramType: ts.Diagnostics.STRATEGY,
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
+        },
+        {
+            name: "baseUrl",
+            type: "string",
+            isFilePath: true,
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names
+        },
+        {
+            // this option can only be specified in tsconfig.json
+            // use type = object to copy the value as-is
+            name: "paths",
+            type: "object",
+            isTSConfigOnly: true,
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl
+        },
+        {
+            // this option can only be specified in tsconfig.json
+            // use type = object to copy the value as-is
+            name: "rootDirs",
+            type: "list",
+            isTSConfigOnly: true,
+            element: {
+                name: "rootDirs",
+                type: "string",
+                isFilePath: true
+            },
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime
+        },
+        {
+            name: "typeRoots",
+            type: "list",
+            element: {
+                name: "typeRoots",
+                type: "string",
+                isFilePath: true
+            },
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from
+        },
+        {
+            name: "types",
+            type: "list",
+            element: {
+                name: "types",
+                type: "string"
+            },
+            showInSimplifiedHelpView: true,
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation
+        },
+        {
+            name: "allowSyntheticDefaultImports",
+            type: "boolean",
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
+        },
+        {
+            name: "preserveSymlinks",
+            type: "boolean",
+            category: ts.Diagnostics.Module_Resolution_Options,
+            description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks,
+        },
+        // Source Maps
+        {
+            name: "sourceRoot",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.LOCATION,
+            category: ts.Diagnostics.Source_Map_Options,
+            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
+        },
+        {
+            name: "mapRoot",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.LOCATION,
+            category: ts.Diagnostics.Source_Map_Options,
+            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
+        },
+        {
+            name: "inlineSourceMap",
+            type: "boolean",
+            category: ts.Diagnostics.Source_Map_Options,
+            description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
+        },
+        {
+            name: "inlineSources",
+            type: "boolean",
+            category: ts.Diagnostics.Source_Map_Options,
+            description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
+        },
+        // Experimental
+        {
+            name: "experimentalDecorators",
+            type: "boolean",
+            category: ts.Diagnostics.Experimental_Options,
+            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
+        },
+        {
+            name: "emitDecoratorMetadata",
+            type: "boolean",
+            category: ts.Diagnostics.Experimental_Options,
+            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
+        },
+        // Advanced
+        {
+            name: "jsxFactory",
+            type: "string",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
+        },
+        {
+            name: "diagnostics",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Show_diagnostic_information
+        },
+        {
+            name: "extendedDiagnostics",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Show_verbose_diagnostic_information
+        },
+        {
+            name: "traceResolution",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
+        },
+        {
+            name: "listFiles",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation
+        },
+        {
+            name: "listEmittedFiles",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation
+        },
+        {
+            name: "out",
+            type: "string",
+            isFilePath: false,
+            // for correct behaviour, please use outFile
+            category: ts.Diagnostics.Advanced_Options,
+            paramType: ts.Diagnostics.FILE,
+            description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file,
+        },
+        {
+            name: "reactNamespace",
+            type: "string",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
+        },
+        {
+            name: "skipDefaultLibCheck",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files
+        },
+        {
+            name: "charset",
+            type: "string",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.The_character_set_of_the_input_files
+        },
+        {
+            name: "emitBOM",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
+        },
+        {
+            name: "locale",
+            type: "string",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
+        },
+        {
+            name: "newLine",
+            type: ts.createMapFromTemplate({
+                "crlf": 0 /* CarriageReturnLineFeed */,
+                "lf": 1 /* LineFeed */
+            }),
+            paramType: ts.Diagnostics.NEWLINE,
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
+        },
+        {
+            name: "noErrorTruncation",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_truncate_error_messages
+        },
+        {
+            name: "noLib",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts
+        },
+        {
+            name: "noResolve",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files
+        },
+        {
+            name: "stripInternal",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
+        },
+        {
+            name: "disableSizeLimit",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects
+        },
+        {
+            name: "noImplicitUseStrict",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
+        },
+        {
+            name: "noEmitHelpers",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
+        },
+        {
+            name: "noEmitOnError",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
+        },
+        {
+            name: "preserveConstEnums",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
+        },
+        {
+            name: "declarationDir",
+            type: "string",
+            isFilePath: true,
+            paramType: ts.Diagnostics.DIRECTORY,
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Output_directory_for_generated_declaration_files
+        },
+        {
+            name: "skipLibCheck",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Skip_type_checking_of_declaration_files,
+        },
+        {
+            name: "allowUnusedLabels",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
+        },
+        {
+            name: "allowUnreachableCode",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
+        },
+        {
+            name: "suppressExcessPropertyErrors",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
+        },
+        {
+            name: "suppressImplicitAnyIndexErrors",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
+        },
+        {
+            name: "forceConsistentCasingInFileNames",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
+        },
+        {
+            name: "maxNodeModuleJsDepth",
+            type: "number",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
+        },
+        {
+            name: "noStrictGenericChecks",
+            type: "boolean",
+            category: ts.Diagnostics.Advanced_Options,
+            description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
+        },
+        {
+            // A list of plugins to load in the language service
+            name: "plugins",
+            type: "list",
+            isTSConfigOnly: true,
+            element: {
+                name: "plugin",
+                type: "object"
+            },
+            description: ts.Diagnostics.List_of_language_service_plugins
+        }
+    ];
+    /* @internal */
+    ts.typeAcquisitionDeclarations = [
+        {
+            /* @deprecated typingOptions.enableAutoDiscovery
+             * Use typeAcquisition.enable instead.
+             */
+            name: "enableAutoDiscovery",
+            type: "boolean",
+        },
+        {
+            name: "enable",
+            type: "boolean",
+        },
+        {
+            name: "include",
+            type: "list",
+            element: {
+                name: "include",
+                type: "string"
+            }
+        },
+        {
+            name: "exclude",
+            type: "list",
+            element: {
+                name: "exclude",
+                type: "string"
+            }
+        }
+    ];
+    /* @internal */
+    ts.defaultInitCompilerOptions = {
+        module: ts.ModuleKind.CommonJS,
+        target: 1 /* ES5 */,
+        strict: true
+    };
+    var optionNameMapCache;
+    /* @internal */
+    function convertEnableAutoDiscoveryToEnable(typeAcquisition) {
+        // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
+        if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
+            var result = {
+                enable: typeAcquisition.enableAutoDiscovery,
+                include: typeAcquisition.include || [],
+                exclude: typeAcquisition.exclude || []
+            };
+            return result;
+        }
+        return typeAcquisition;
+    }
+    ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable;
+    function getOptionNameMap() {
+        if (optionNameMapCache) {
+            return optionNameMapCache;
+        }
+        var optionNameMap = ts.createMap();
+        var shortOptionNames = ts.createMap();
+        ts.forEach(ts.optionDeclarations, function (option) {
+            optionNameMap.set(option.name.toLowerCase(), option);
+            if (option.shortName) {
+                shortOptionNames.set(option.shortName, option.name);
+            }
+        });
+        optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames };
+        return optionNameMapCache;
+    }
+    /* @internal */
+    function createCompilerDiagnosticForInvalidCustomType(opt) {
+        return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic);
+    }
+    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
+    function createDiagnosticForInvalidCustomType(opt, createDiagnostic) {
+        var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", ");
+        return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
+    }
+    /* @internal */
+    function parseCustomTypeOption(opt, value, errors) {
+        return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
+    }
+    ts.parseCustomTypeOption = parseCustomTypeOption;
+    /* @internal */
+    function parseListTypeOption(opt, value, errors) {
+        if (value === void 0) { value = ""; }
+        value = trimString(value);
+        if (ts.startsWith(value, "-")) {
+            return undefined;
+        }
+        if (value === "") {
+            return [];
+        }
+        var values = value.split(",");
+        switch (opt.element.type) {
+            case "number":
+                return ts.map(values, parseInt);
+            case "string":
+                return ts.map(values, function (v) { return v || ""; });
+            default:
+                return ts.filter(ts.map(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); }), function (v) { return !!v; });
+        }
+    }
+    ts.parseListTypeOption = parseListTypeOption;
+    function parseCommandLine(commandLine, readFile) {
+        var options = {};
+        var fileNames = [];
+        var errors = [];
+        parseStrings(commandLine);
+        return {
+            options: options,
+            fileNames: fileNames,
+            errors: errors
+        };
+        function parseStrings(args) {
+            var i = 0;
+            while (i < args.length) {
+                var s = args[i];
+                i++;
+                if (s.charCodeAt(0) === 64 /* at */) {
+                    parseResponseFile(s.slice(1));
+                }
+                else if (s.charCodeAt(0) === 45 /* minus */) {
+                    var opt = getOptionFromName(s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1), /*allowShort*/ true);
+                    if (opt) {
+                        if (opt.isTSConfigOnly) {
+                            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
+                        }
+                        else {
+                            // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
+                            if (!args[i] && opt.type !== "boolean") {
+                                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
+                            }
+                            switch (opt.type) {
+                                case "number":
+                                    options[opt.name] = parseInt(args[i]);
+                                    i++;
+                                    break;
+                                case "boolean":
+                                    // boolean flag has optional value true, false, others
+                                    var optValue = args[i];
+                                    options[opt.name] = optValue !== "false";
+                                    // consume next argument as boolean flag value
+                                    if (optValue === "false" || optValue === "true") {
+                                        i++;
+                                    }
+                                    break;
+                                case "string":
+                                    options[opt.name] = args[i] || "";
+                                    i++;
+                                    break;
+                                case "list":
+                                    var result = parseListTypeOption(opt, args[i], errors);
+                                    options[opt.name] = result || [];
+                                    if (result) {
+                                        i++;
+                                    }
+                                    break;
+                                // If not a primitive, the possible types are specified in what is effectively a map of options.
+                                default:
+                                    options[opt.name] = parseCustomTypeOption(opt, args[i], errors);
+                                    i++;
+                                    break;
+                            }
+                        }
+                    }
+                    else {
+                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_compiler_option_0, s));
+                    }
+                }
+                else {
+                    fileNames.push(s);
+                }
+            }
+        }
+        function parseResponseFile(fileName) {
+            var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName);
+            if (!text) {
+                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName));
+                return;
+            }
+            var args = [];
+            var pos = 0;
+            while (true) {
+                while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */)
+                    pos++;
+                if (pos >= text.length)
+                    break;
+                var start = pos;
+                if (text.charCodeAt(start) === 34 /* doubleQuote */) {
+                    pos++;
+                    while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */)
+                        pos++;
+                    if (pos < text.length) {
+                        args.push(text.substring(start + 1, pos));
+                        pos++;
+                    }
+                    else {
+                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName));
+                    }
+                }
+                else {
+                    while (text.charCodeAt(pos) > 32 /* space */)
+                        pos++;
+                    args.push(text.substring(start, pos));
+                }
+            }
+            parseStrings(args);
+        }
+    }
+    ts.parseCommandLine = parseCommandLine;
+    function getOptionFromName(optionName, allowShort) {
+        if (allowShort === void 0) { allowShort = false; }
+        optionName = optionName.toLowerCase();
+        var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames;
+        // Try to translate short option names to their full equivalents.
+        if (allowShort) {
+            var short = shortOptionNames.get(optionName);
+            if (short !== undefined) {
+                optionName = short;
+            }
+        }
+        return optionNameMap.get(optionName);
+    }
+    /**
+     * Read tsconfig.json file
+     * @param fileName The path to the config file
+     */
+    function readConfigFile(fileName, readFile) {
+        var textOrDiagnostic = tryReadFile(fileName, readFile);
+        return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
+    }
+    ts.readConfigFile = readConfigFile;
+    /**
+     * Parse the text of the tsconfig.json file
+     * @param fileName The path to the config file
+     * @param jsonText The text of the config file
+     */
+    function parseConfigFileTextToJson(fileName, jsonText) {
+        var jsonSourceFile = ts.parseJsonText(fileName, jsonText);
+        return {
+            config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics),
+            error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
+        };
+    }
+    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
+    /**
+     * Read tsconfig.json file
+     * @param fileName The path to the config file
+     */
+    function readJsonConfigFile(fileName, readFile) {
+        var textOrDiagnostic = tryReadFile(fileName, readFile);
+        return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] };
+    }
+    ts.readJsonConfigFile = readJsonConfigFile;
+    function tryReadFile(fileName, readFile) {
+        var text;
+        try {
+            text = readFile(fileName);
+        }
+        catch (e) {
+            return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
+        }
+        return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text;
+    }
+    function commandLineOptionsToMap(options) {
+        return ts.arrayToMap(options, function (option) { return option.name; });
+    }
+    var _tsconfigRootOptions;
+    function getTsconfigRootOptionsMap() {
+        if (_tsconfigRootOptions === undefined) {
+            _tsconfigRootOptions = commandLineOptionsToMap([
+                {
+                    name: "compilerOptions",
+                    type: "object",
+                    elementOptions: commandLineOptionsToMap(ts.optionDeclarations),
+                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_compiler_option_0
+                },
+                {
+                    name: "typingOptions",
+                    type: "object",
+                    elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
+                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
+                },
+                {
+                    name: "typeAcquisition",
+                    type: "object",
+                    elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
+                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
+                },
+                {
+                    name: "extends",
+                    type: "string"
+                },
+                {
+                    name: "files",
+                    type: "list",
+                    element: {
+                        name: "files",
+                        type: "string"
+                    }
+                },
+                {
+                    name: "include",
+                    type: "list",
+                    element: {
+                        name: "include",
+                        type: "string"
+                    }
+                },
+                {
+                    name: "exclude",
+                    type: "list",
+                    element: {
+                        name: "exclude",
+                        type: "string"
+                    }
+                },
+                ts.compileOnSaveCommandLineOption
+            ]);
+        }
+        return _tsconfigRootOptions;
+    }
+    /**
+     * Convert the json syntax tree into the json value
+     */
+    function convertToObject(sourceFile, errors) {
+        return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
+    }
+    ts.convertToObject = convertToObject;
+    /**
+     * Convert the json syntax tree into the json value
+     */
+    function convertToObjectWorker(sourceFile, errors, knownRootOptions, jsonConversionNotifier) {
+        if (!sourceFile.jsonObject) {
+            return {};
+        }
+        return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions, 
+        /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined);
+        function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnosticMessage, parentOption) {
+            var result = {};
+            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+                var element = _a[_i];
+                if (element.kind !== 261 /* PropertyAssignment */) {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected));
+                    continue;
+                }
+                if (element.questionToken) {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
+                }
+                if (!isDoubleQuotedString(element.name)) {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected));
+                }
+                var keyText = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(element.name));
+                var option = knownOptions ? knownOptions.get(keyText) : undefined;
+                if (extraKeyDiagnosticMessage && !option) {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
+                }
+                var value = convertPropertyValueToJson(element.initializer, option);
+                if (typeof keyText !== "undefined") {
+                    result[keyText] = value;
+                    // Notify key value set, if user asked for it
+                    if (jsonConversionNotifier &&
+                        // Current callbacks are only on known parent option or if we are setting values in the root
+                        (parentOption || knownOptions === knownRootOptions)) {
+                        var isValidOptionValue = isCompilerOptionsValue(option, value);
+                        if (parentOption) {
+                            if (isValidOptionValue) {
+                                // Notify option set in the parent if its a valid option value
+                                jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
+                            }
+                        }
+                        else if (knownOptions === knownRootOptions) {
+                            if (isValidOptionValue) {
+                                // Notify about the valid root key value being set
+                                jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
+                            }
+                            else if (!option) {
+                                // Notify about the unknown root key value being set
+                                jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
+                            }
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+        function convertArrayLiteralExpressionToJson(elements, elementOption) {
+            return elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); });
+        }
+        function convertPropertyValueToJson(valueExpression, option) {
+            switch (valueExpression.kind) {
+                case 101 /* TrueKeyword */:
+                    reportInvalidOptionValue(option && option.type !== "boolean");
+                    return true;
+                case 86 /* FalseKeyword */:
+                    reportInvalidOptionValue(option && option.type !== "boolean");
+                    return false;
+                case 95 /* NullKeyword */:
+                    reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
+                    return null; // tslint:disable-line:no-null-keyword
+                case 9 /* StringLiteral */:
+                    if (!isDoubleQuotedString(valueExpression)) {
+                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected));
+                    }
+                    reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string"));
+                    var text = valueExpression.text;
+                    if (option && !ts.isString(option.type)) {
+                        var customOption = option;
+                        // Validate custom option type
+                        if (!customOption.type.has(text.toLowerCase())) {
+                            errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); }));
+                        }
+                    }
+                    return text;
+                case 8 /* NumericLiteral */:
+                    reportInvalidOptionValue(option && option.type !== "number");
+                    return Number(valueExpression.text);
+                case 178 /* ObjectLiteralExpression */:
+                    reportInvalidOptionValue(option && option.type !== "object");
+                    var objectLiteralExpression = valueExpression;
+                    // Currently having element option declaration in the tsconfig with type "object"
+                    // determines if it needs onSetValidOptionKeyValueInParent callback or not
+                    // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions"
+                    // that satifies it and need it to modify options set in them (for normalizing file paths)
+                    // vs what we set in the json
+                    // If need arises, we can modify this interface and callbacks as needed
+                    if (option) {
+                        var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnosticMessage = _a.extraKeyDiagnosticMessage, optionName = _a.name;
+                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnosticMessage, optionName);
+                    }
+                    else {
+                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, 
+                        /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined);
+                    }
+                case 177 /* ArrayLiteralExpression */:
+                    reportInvalidOptionValue(option && option.type !== "list");
+                    return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element);
+            }
+            // Not in expected format
+            if (option) {
+                reportInvalidOptionValue(/*isError*/ true);
+            }
+            else {
+                errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal));
+            }
+            return undefined;
+            function reportInvalidOptionValue(isError) {
+                if (isError) {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
+                }
+            }
+        }
+        function isDoubleQuotedString(node) {
+            return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile);
+        }
+    }
+    function getCompilerOptionValueTypeString(option) {
+        return option.type === "list" ?
+            "Array" :
+            ts.isString(option.type) ? option.type : "string";
+    }
+    function isCompilerOptionsValue(option, value) {
+        if (option) {
+            if (isNullOrUndefined(value))
+                return true; // All options are undefinable/nullable
+            if (option.type === "list") {
+                return ts.isArray(value);
+            }
+            var expectedType = ts.isString(option.type) ? option.type : "string";
+            return typeof value === expectedType;
+        }
+    }
+    /**
+     * Generate tsconfig configuration when running command line "--init"
+     * @param options commandlineOptions to be generated into tsconfig.json
+     * @param fileNames array of filenames to be generated into tsconfig.json
+     */
+    /* @internal */
+    function generateTSConfig(options, fileNames, newLine) {
+        var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions);
+        var compilerOptionsMap = serializeCompilerOptions(compilerOptions);
+        return writeConfigurations();
+        function getCustomTypeMapOfCommandLineOption(optionDefinition) {
+            if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
+                // this is of a type CommandLineOptionOfPrimitiveType
+                return undefined;
+            }
+            else if (optionDefinition.type === "list") {
+                return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
+            }
+            else {
+                return optionDefinition.type;
+            }
+        }
+        function getNameOfCompilerOptionValue(value, customTypeMap) {
+            // There is a typeMap associated with this command-line option so use it to map value back to its name
+            return ts.forEachEntry(customTypeMap, function (mapValue, key) {
+                if (mapValue === value) {
+                    return key;
+                }
+            });
+        }
+        function serializeCompilerOptions(options) {
+            var result = ts.createMap();
+            var optionsNameMap = getOptionNameMap().optionNameMap;
+            var _loop_5 = function (name) {
+                if (ts.hasProperty(options, name)) {
+                    // tsconfig only options cannot be specified via command line,
+                    // so we can assume that only types that can appear here string | number | boolean
+                    if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) {
+                        return "continue";
+                    }
+                    var value = options[name];
+                    var optionDefinition = optionsNameMap.get(name.toLowerCase());
+                    if (optionDefinition) {
+                        var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition);
+                        if (!customTypeMap_1) {
+                            // There is no map associated with this compiler option then use the value as-is
+                            // This is the case if the value is expect to be string, number, boolean or list of string
+                            result.set(name, value);
+                        }
+                        else {
+                            if (optionDefinition.type === "list") {
+                                result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); }));
+                            }
+                            else {
+                                // There is a typeMap associated with this command-line option so use it to map value back to its name
+                                result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1));
+                            }
+                        }
+                    }
+                }
+            };
+            for (var name in options) {
+                _loop_5(name);
+            }
+            return result;
+        }
+        function getDefaultValueForOption(option) {
+            switch (option.type) {
+                case "number":
+                    return 1;
+                case "boolean":
+                    return true;
+                case "string":
+                    return option.isFilePath ? "./" : "";
+                case "list":
+                    return [];
+                case "object":
+                    return {};
+                default:
+                    return option.type.keys().next().value;
+            }
+        }
+        function makePadding(paddingLength) {
+            return Array(paddingLength + 1).join(" ");
+        }
+        function writeConfigurations() {
+            // Filter applicable options to place in the file
+            var categorizedOptions = ts.createMultiMap();
+            for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) {
+                var option = optionDeclarations_1[_i];
+                var category = option.category;
+                if (category !== undefined && category !== ts.Diagnostics.Command_line_Options && category !== ts.Diagnostics.Advanced_Options) {
+                    categorizedOptions.add(ts.getLocaleSpecificMessage(category), option);
+                }
+            }
+            // Serialize all options and their descriptions
+            var marginLength = 0;
+            var seenKnownKeys = 0;
+            var nameColumn = [];
+            var descriptionColumn = [];
+            categorizedOptions.forEach(function (options, category) {
+                if (nameColumn.length !== 0) {
+                    nameColumn.push("");
+                    descriptionColumn.push("");
+                }
+                nameColumn.push("/* " + category + " */");
+                descriptionColumn.push("");
+                for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
+                    var option = options_1[_i];
+                    var optionName = void 0;
+                    if (compilerOptionsMap.has(option.name)) {
+                        optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ",");
+                    }
+                    else {
+                        optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ",";
+                    }
+                    nameColumn.push(optionName);
+                    descriptionColumn.push("/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */");
+                    marginLength = Math.max(optionName.length, marginLength);
+                }
+            });
+            // Write the output
+            var tab = makePadding(2);
+            var result = [];
+            result.push("{");
+            result.push(tab + "\"compilerOptions\": {");
+            // Print out each row, aligning all the descriptions on the same column.
+            for (var i = 0; i < nameColumn.length; i++) {
+                var optionName = nameColumn[i];
+                var description = descriptionColumn[i];
+                result.push(optionName && "" + tab + tab + optionName + (description && (makePadding(marginLength - optionName.length + 2) + description)));
+            }
+            if (fileNames.length) {
+                result.push(tab + "},");
+                result.push(tab + "\"files\": [");
+                for (var i = 0; i < fileNames.length; i++) {
+                    result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ","));
+                }
+                result.push(tab + "]");
+            }
+            else {
+                result.push(tab + "}");
+            }
+            result.push("}");
+            return result.join(newLine);
+        }
+    }
+    ts.generateTSConfig = generateTSConfig;
+    /**
+     * Parse the contents of a config file (tsconfig.json).
+     * @param json The contents of the config file to parse
+     * @param host Instance of ParseConfigHost used to enumerate files in folder.
+     * @param basePath A root directory to resolve relative path entries in the config
+     *    file to. e.g. outDir
+     */
+    function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
+        return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
+    }
+    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
+    /**
+     * Parse the contents of a config file (tsconfig.json).
+     * @param jsonNode The contents of the config file to parse
+     * @param host Instance of ParseConfigHost used to enumerate files in folder.
+     * @param basePath A root directory to resolve relative path entries in the config
+     *    file to. e.g. outDir
+     */
+    function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
+        return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
+    }
+    ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent;
+    /*@internal*/
+    function setConfigFileInOptions(options, configFile) {
+        if (configFile) {
+            Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
+        }
+    }
+    ts.setConfigFileInOptions = setConfigFileInOptions;
+    function isNullOrUndefined(x) {
+        // tslint:disable-next-line:no-null-keyword
+        return x === undefined || x === null;
+    }
+    function directoryOfCombinedPath(fileName, basePath) {
+        // Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical
+        // until consistient casing errors are reported
+        return ts.getDirectoryPath(ts.toPath(fileName, basePath, ts.identity));
+    }
+    /**
+     * Parse the contents of a config file from json or json source file (tsconfig.json).
+     * @param json The contents of the config file to parse
+     * @param sourceFile sourceFile corresponding to the Json
+     * @param host Instance of ParseConfigHost used to enumerate files in folder.
+     * @param basePath A root directory to resolve relative path entries in the config
+     *    file to. e.g. outDir
+     * @param resolutionStack Only present for backwards-compatibility. Should be empty.
+     */
+    function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
+        if (existingOptions === void 0) { existingOptions = {}; }
+        if (resolutionStack === void 0) { resolutionStack = []; }
+        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
+        ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
+        var errors = [];
+        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
+        var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors);
+        var raw = parsedConfig.raw;
+        var options = ts.extend(existingOptions, parsedConfig.options || {});
+        options.configFilePath = configFileName;
+        setConfigFileInOptions(options, sourceFile);
+        var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec;
+        return {
+            options: options,
+            fileNames: fileNames,
+            typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
+            raw: raw,
+            errors: errors,
+            wildcardDirectories: wildcardDirectories,
+            compileOnSave: !!raw.compileOnSave,
+            configFileSpecs: spec
+        };
+        function getFileNames() {
+            var filesSpecs;
+            if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
+                if (ts.isArray(raw.files)) {
+                    filesSpecs = raw.files;
+                    if (filesSpecs.length === 0) {
+                        createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
+                    }
+                }
+                else {
+                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array");
+                }
+            }
+            var includeSpecs;
+            if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
+                if (ts.isArray(raw.include)) {
+                    includeSpecs = raw.include;
+                }
+                else {
+                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
+                }
+            }
+            var excludeSpecs;
+            if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
+                if (ts.isArray(raw.exclude)) {
+                    excludeSpecs = raw.exclude;
+                }
+                else {
+                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
+                }
+            }
+            else {
+                var outDir = raw.compilerOptions && raw.compilerOptions.outDir;
+                if (outDir) {
+                    excludeSpecs = [outDir];
+                }
+            }
+            if (filesSpecs === undefined && includeSpecs === undefined) {
+                includeSpecs = ["**/*"];
+            }
+            var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
+            if (result.fileNames.length === 0 && !ts.hasProperty(raw, "files") && resolutionStack.length === 0) {
+                errors.push(getErrorForNoInputFiles(result.spec, configFileName));
+            }
+            return result;
+        }
+        function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) {
+            if (!sourceFile) {
+                errors.push(ts.createCompilerDiagnostic(message, arg0, arg1));
+            }
+        }
+    }
+    /*@internal*/
+    function isErrorNoInputFiles(error) {
+        return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
+    }
+    ts.isErrorNoInputFiles = isErrorNoInputFiles;
+    /*@internal*/
+    function getErrorForNoInputFiles(_a, configFileName) {
+        var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs;
+        return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || []));
+    }
+    ts.getErrorForNoInputFiles = getErrorForNoInputFiles;
+    function isSuccessfulParsedTsconfig(value) {
+        return !!value.options;
+    }
+    /**
+     * This *just* extracts options/include/exclude/files out of a config file.
+     * It does *not* resolve the included files.
+     */
+    function parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors) {
+        basePath = ts.normalizeSlashes(basePath);
+        var resolvedPath = ts.toPath(configFileName || "", basePath, getCanonicalFileName);
+        if (resolutionStack.indexOf(resolvedPath) >= 0) {
+            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, resolutionStack.concat([resolvedPath]).join(" -> ")));
+            return { raw: json || convertToObject(sourceFile, errors) };
+        }
+        var ownConfig = json ?
+            parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) :
+            parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors);
+        if (ownConfig.extendedConfigPath) {
+            // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
+            resolutionStack = resolutionStack.concat([resolvedPath]);
+            var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors);
+            if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
+                var baseRaw_1 = extendedConfig.raw;
+                var raw_1 = ownConfig.raw;
+                var setPropertyInRawIfNotUndefined = function (propertyName) {
+                    var value = raw_1[propertyName] || baseRaw_1[propertyName];
+                    if (value) {
+                        raw_1[propertyName] = value;
+                    }
+                };
+                setPropertyInRawIfNotUndefined("include");
+                setPropertyInRawIfNotUndefined("exclude");
+                setPropertyInRawIfNotUndefined("files");
+                if (raw_1.compileOnSave === undefined) {
+                    raw_1.compileOnSave = baseRaw_1.compileOnSave;
+                }
+                ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options);
+                // TODO extend type typeAcquisition
+            }
+        }
+        return ownConfig;
+    }
+    function parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) {
+        if (ts.hasProperty(json, "excludes")) {
+            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
+        }
+        var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
+        // typingOptions has been deprecated and is only supported for backward compatibility purposes.
+        // It should be removed in future releases - use typeAcquisition instead.
+        var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
+        json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
+        var extendedConfigPath;
+        if (json.extends) {
+            if (!ts.isString(json.extends)) {
+                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
+            }
+            else {
+                var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
+                extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, ts.createCompilerDiagnostic);
+            }
+        }
+        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
+    }
+    function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors) {
+        var options = getDefaultCompilerOptions(configFileName);
+        var typeAcquisition, typingOptionstypeAcquisition;
+        var extendedConfigPath;
+        var optionsIterator = {
+            onSetValidOptionKeyValueInParent: function (parentOption, option, value) {
+                ts.Debug.assert(parentOption === "compilerOptions" || parentOption === "typeAcquisition" || parentOption === "typingOptions");
+                var currentOption = parentOption === "compilerOptions" ?
+                    options :
+                    parentOption === "typeAcquisition" ?
+                        (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName))) :
+                        (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName)));
+                currentOption[option.name] = normalizeOptionValue(option, basePath, value);
+            },
+            onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) {
+                switch (key) {
+                    case "extends":
+                        var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
+                        extendedConfigPath = getExtendsConfigPath(value, host, newBase, getCanonicalFileName, errors, function (message, arg0) {
+                            return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0);
+                        });
+                        return;
+                    case "files":
+                        if (value.length === 0) {
+                            errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
+                        }
+                        return;
+                }
+            },
+            onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) {
+                if (key === "excludes") {
+                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
+                }
+            }
+        };
+        var json = convertToObjectWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator);
+        if (!typeAcquisition) {
+            if (typingOptionstypeAcquisition) {
+                typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
+                    {
+                        enable: typingOptionstypeAcquisition.enableAutoDiscovery,
+                        include: typingOptionstypeAcquisition.include,
+                        exclude: typingOptionstypeAcquisition.exclude
+                    } :
+                    typingOptionstypeAcquisition;
+            }
+            else {
+                typeAcquisition = getDefaultTypeAcquisition(configFileName);
+            }
+        }
+        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
+    }
+    function getExtendsConfigPath(extendedConfig, host, basePath, getCanonicalFileName, errors, createDiagnostic) {
+        extendedConfig = ts.normalizeSlashes(extendedConfig);
+        // If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
+        if (!(ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../"))) {
+            errors.push(createDiagnostic(ts.Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
+            return undefined;
+        }
+        var extendedConfigPath = ts.toPath(extendedConfig, basePath, getCanonicalFileName);
+        if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) {
+            extendedConfigPath = extendedConfigPath + ".json";
+            if (!host.fileExists(extendedConfigPath)) {
+                errors.push(createDiagnostic(ts.Diagnostics.File_0_does_not_exist, extendedConfig));
+                return undefined;
+            }
+        }
+        return extendedConfigPath;
+    }
+    function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors) {
+        var extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); });
+        if (sourceFile) {
+            (sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName);
+        }
+        if (extendedResult.parseDiagnostics.length) {
+            errors.push.apply(errors, extendedResult.parseDiagnostics);
+            return undefined;
+        }
+        var extendedDirname = ts.getDirectoryPath(extendedConfigPath);
+        var extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), getCanonicalFileName, resolutionStack, errors);
+        if (sourceFile) {
+            (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles);
+        }
+        if (isSuccessfulParsedTsconfig(extendedConfig)) {
+            // Update the paths to reflect base path
+            var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, getCanonicalFileName);
+            var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); };
+            var mapPropertiesInRawIfNotUndefined = function (propertyName) {
+                if (raw_2[propertyName]) {
+                    raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1);
+                }
+            };
+            var raw_2 = extendedConfig.raw;
+            mapPropertiesInRawIfNotUndefined("include");
+            mapPropertiesInRawIfNotUndefined("exclude");
+            mapPropertiesInRawIfNotUndefined("files");
+        }
+        return extendedConfig;
+        var _a;
+    }
+    function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) {
+        if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) {
+            return undefined;
+        }
+        var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
+        if (typeof result === "boolean" && result) {
+            return result;
+        }
+        return false;
+    }
+    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
+        var errors = [];
+        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
+        return { options: options, errors: errors };
+    }
+    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
+    function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) {
+        var errors = [];
+        var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
+        return { options: options, errors: errors };
+    }
+    ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson;
+    function getDefaultCompilerOptions(configFileName) {
+        var options = ts.getBaseFileName(configFileName) === "jsconfig.json"
+            ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
+            : {};
+        return options;
+    }
+    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
+        var options = getDefaultCompilerOptions(configFileName);
+        convertOptionsFromJson(ts.optionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_compiler_option_0, errors);
+        return options;
+    }
+    function getDefaultTypeAcquisition(configFileName) {
+        var options = { enable: ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
+        return options;
+    }
+    function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
+        var options = getDefaultTypeAcquisition(configFileName);
+        var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
+        convertOptionsFromJson(ts.typeAcquisitionDeclarations, typeAcquisition, basePath, options, ts.Diagnostics.Unknown_type_acquisition_option_0, errors);
+        return options;
+    }
+    function convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, defaultOptions, diagnosticMessage, errors) {
+        if (!jsonOptions) {
+            return;
+        }
+        var optionNameMap = commandLineOptionsToMap(optionDeclarations);
+        for (var id in jsonOptions) {
+            var opt = optionNameMap.get(id);
+            if (opt) {
+                defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
+            }
+            else {
+                errors.push(ts.createCompilerDiagnostic(diagnosticMessage, id));
+            }
+        }
+    }
+    function convertJsonOption(opt, value, basePath, errors) {
+        if (isCompilerOptionsValue(opt, value)) {
+            var optType = opt.type;
+            if (optType === "list" && ts.isArray(value)) {
+                return convertJsonOptionOfListType(opt, value, basePath, errors);
+            }
+            else if (!ts.isString(optType)) {
+                return convertJsonOptionOfCustomType(opt, value, errors);
+            }
+            return normalizeNonListOptionValue(opt, basePath, value);
+        }
+        else {
+            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt)));
+        }
+    }
+    function normalizeOptionValue(option, basePath, value) {
+        if (isNullOrUndefined(value))
+            return undefined;
+        if (option.type === "list") {
+            var listOption_1 = option;
+            if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) {
+                return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; });
+            }
+            return value;
+        }
+        else if (!ts.isString(option.type)) {
+            return option.type.get(ts.isString(value) ? value.toLowerCase() : value);
+        }
+        return normalizeNonListOptionValue(option, basePath, value);
+    }
+    function normalizeNonListOptionValue(option, basePath, value) {
+        if (option.isFilePath) {
+            value = ts.normalizePath(ts.combinePaths(basePath, value));
+            if (value === "") {
+                value = ".";
+            }
+        }
+        return value;
+    }
+    function convertJsonOptionOfCustomType(opt, value, errors) {
+        if (isNullOrUndefined(value))
+            return undefined;
+        var key = value.toLowerCase();
+        var val = opt.type.get(key);
+        if (val !== undefined) {
+            return val;
+        }
+        else {
+            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
+        }
+    }
+    function convertJsonOptionOfListType(option, values, basePath, errors) {
+        return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; });
+    }
+    function trimString(s) {
+        return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, "");
+    }
+    /**
+     * Tests for a path that ends in a recursive directory wildcard.
+     * Matches **, \**, **\, and \**\, but not a**b.
+     *
+     * NOTE: used \ in place of / above to avoid issues with multiline comments.
+     *
+     * Breakdown:
+     *  (^|\/)      # matches either the beginning of the string or a directory separator.
+     *  \*\*        # matches the recursive directory wildcard "**".
+     *  \/?$        # matches an optional trailing directory separator at the end of the string.
+     */
+    var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
+    /**
+     * Tests for a path with multiple recursive directory wildcards.
+     * Matches **\** and **\a\**, but not **\a**b.
+     *
+     * NOTE: used \ in place of / above to avoid issues with multiline comments.
+     *
+     * Breakdown:
+     *  (^|\/)      # matches either the beginning of the string or a directory separator.
+     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
+     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
+     *  \*\*        # matches a recursive directory wildcard "**"
+     *  ($|\/)      # matches either the end of the string or a directory separator.
+     */
+    var invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/;
+    /**
+     * Tests for a path where .. appears after a recursive directory wildcard.
+     * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
+     *
+     * NOTE: used \ in place of / above to avoid issues with multiline comments.
+     *
+     * Breakdown:
+     *  (^|\/)      # matches either the beginning of the string or a directory separator.
+     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
+     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
+     *  \.\.        # matches a parent directory path component ".."
+     *  ($|\/)      # matches either the end of the string or a directory separator.
+     */
+    var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
+    /**
+     * Tests for a path containing a wildcard character in a directory component of the path.
+     * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
+     *
+     * NOTE: used \ in place of / above to avoid issues with multiline comments.
+     *
+     * Breakdown:
+     *  \/          # matches a directory separator.
+     *  [^/]*?      # matches any number of characters excluding directory separators (non-greedy).
+     *  [*?]        # matches either a wildcard character (* or ?)
+     *  [^/]*       # matches any number of characters excluding directory separators (greedy).
+     *  \/          # matches a directory separator.
+     */
+    var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//;
+    /**
+     * Matches the portion of a wildcard path that does not contain wildcards.
+     * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d.
+     *
+     * NOTE: used \ in place of / above to avoid issues with multiline comments.
+     *
+     * Breakdown:
+     *  ^                   # matches the beginning of the string
+     *  [^*?]*              # matches any number of non-wildcard characters
+     *  (?=\/[^/]*[*?])     # lookahead that matches a directory separator followed by
+     *                      # a path component that contains at least one wildcard character (* or ?).
+     */
+    var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
+    /**
+     * Expands an array of file specifications.
+     *
+     * @param filesSpecs The literal file names to include.
+     * @param includeSpecs The wildcard file specifications to include.
+     * @param excludeSpecs The wildcard file specifications to exclude.
+     * @param basePath The base path for any relative file specifications.
+     * @param options Compiler options.
+     * @param host The host used to resolve files and directories.
+     * @param errors An array for diagnostic reporting.
+     */
+    function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) {
+        basePath = ts.normalizePath(basePath);
+        var validatedIncludeSpecs, validatedExcludeSpecs;
+        // The exclude spec list is converted into a regular expression, which allows us to quickly
+        // test whether a file or directory should be excluded before recursively traversing the
+        // file system.
+        if (includeSpecs) {
+            validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
+        }
+        if (excludeSpecs) {
+            validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
+        }
+        // Wildcard directories (provided as part of a wildcard path) are stored in a
+        // file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
+        // or a recursive directory. This information is used by filesystem watchers to monitor for
+        // new entries in these paths.
+        var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
+        var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories };
+        return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
+    }
+    /**
+     * Gets the file names from the provided config file specs that contain, files, include, exclude and
+     * other properties needed to resolve the file names
+     * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details
+     * @param basePath The base path for any relative file specifications.
+     * @param options Compiler options.
+     * @param host The host used to resolve files and directories.
+     * @param extraFileExtensions optionaly file extra file extension information from host
+     */
+    /* @internal */
+    function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) {
+        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
+        basePath = ts.normalizePath(basePath);
+        var keyMapper = host.useCaseSensitiveFileNames ? caseSensitiveKeyMapper : caseInsensitiveKeyMapper;
+        // Literal file names (provided via the "files" array in tsconfig.json) are stored in a
+        // file map with a possibly case insensitive key. We use this map later when when including
+        // wildcard paths.
+        var literalFileMap = ts.createMap();
+        // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
+        // file map with a possibly case insensitive key. We use this map to store paths matched
+        // via wildcard, and to handle extension priority.
+        var wildcardFileMap = ts.createMap();
+        var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories;
+        // Rather than requery this for each file and filespec, we query the supported extensions
+        // once and store it on the expansion context.
+        var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions);
+        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
+        // remove a literal file.
+        if (filesSpecs) {
+            for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) {
+                var fileName = filesSpecs_1[_i];
+                var file = ts.getNormalizedAbsolutePath(fileName, basePath);
+                literalFileMap.set(keyMapper(file), file);
+            }
+        }
+        if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
+            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) {
+                var file = _b[_a];
+                // If we have already included a literal or wildcard path with a
+                // higher priority extension, we should skip this file.
+                //
+                // This handles cases where we may encounter both <file>.ts and
+                // <file>.d.ts (or <file>.js if "allowJs" is enabled) in the same
+                // directory when they are compilation outputs.
+                if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) {
+                    continue;
+                }
+                // We may have included a wildcard path with a lower priority
+                // extension due to the user-defined order of entries in the
+                // "include" array. If there is a lower priority extension in the
+                // same directory, we should remove it.
+                removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
+                var key = keyMapper(file);
+                if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
+                    wildcardFileMap.set(key, file);
+                }
+            }
+        }
+        var literalFiles = ts.arrayFrom(literalFileMap.values());
+        var wildcardFiles = ts.arrayFrom(wildcardFileMap.values());
+        return {
+            fileNames: literalFiles.concat(wildcardFiles),
+            wildcardDirectories: wildcardDirectories,
+            spec: spec
+        };
+    }
+    ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs;
+    function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) {
+        return specs.filter(function (spec) {
+            var diag = specToDiagnostic(spec, allowTrailingRecursion);
+            if (diag !== undefined) {
+                errors.push(createDiagnostic(diag, spec));
+            }
+            return diag === undefined;
+        });
+        function createDiagnostic(message, spec) {
+            if (jsonSourceFile && jsonSourceFile.jsonObject) {
+                for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) {
+                    var property = _a[_i];
+                    if (ts.isArrayLiteralExpression(property.initializer)) {
+                        for (var _b = 0, _c = property.initializer.elements; _b < _c.length; _b++) {
+                            var element = _c[_b];
+                            if (ts.isStringLiteral(element) && element.text === spec) {
+                                return ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
+                            }
+                        }
+                    }
+                }
+            }
+            return ts.createCompilerDiagnostic(message, spec);
+        }
+    }
+    function specToDiagnostic(spec, allowTrailingRecursion) {
+        if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
+            return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
+        }
+        else if (invalidMultipleRecursionPatterns.test(spec)) {
+            return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0;
+        }
+        else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
+            return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
+        }
+    }
+    /**
+     * Gets directories in a set of include patterns that should be watched for changes.
+     */
+    function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) {
+        // We watch a directory recursively if it contains a wildcard anywhere in a directory segment
+        // of the pattern:
+        //
+        //  /a/b/**/d   - Watch /a/b recursively to catch changes to any d in any subfolder recursively
+        //  /a/b/*/d    - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
+        //  /a/b        - Watch /a/b recursively to catch changes to anything in any recursive subfoler
+        //
+        // We watch a directory without recursion if it contains a wildcard in the file segment of
+        // the pattern:
+        //
+        //  /a/b/*      - Watch /a/b directly to catch any new file
+        //  /a/b/a?z    - Watch /a/b directly to catch any new file matching a?z
+        var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude");
+        var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
+        var wildcardDirectories = {};
+        if (include !== undefined) {
+            var recursiveKeys = [];
+            for (var _i = 0, include_1 = include; _i < include_1.length; _i++) {
+                var file = include_1[_i];
+                var spec = ts.normalizePath(ts.combinePaths(path, file));
+                if (excludeRegex && excludeRegex.test(spec)) {
+                    continue;
+                }
+                var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
+                if (match) {
+                    var key = match.key, flags = match.flags;
+                    var existingFlags = wildcardDirectories[key];
+                    if (existingFlags === undefined || existingFlags < flags) {
+                        wildcardDirectories[key] = flags;
+                        if (flags === 1 /* Recursive */) {
+                            recursiveKeys.push(key);
+                        }
+                    }
+                }
+            }
+            // Remove any subpaths under an existing recursively watched directory.
+            for (var key in wildcardDirectories) {
+                if (ts.hasProperty(wildcardDirectories, key)) {
+                    for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) {
+                        var recursiveKey = recursiveKeys_1[_a];
+                        if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
+                            delete wildcardDirectories[key];
+                        }
+                    }
+                }
+            }
+        }
+        return wildcardDirectories;
+    }
+    function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) {
+        var match = wildcardDirectoryPattern.exec(spec);
+        if (match) {
+            return {
+                key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
+                flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */
+            };
+        }
+        if (ts.isImplicitGlob(spec)) {
+            return { key: spec, flags: 1 /* Recursive */ };
+        }
+        return undefined;
+    }
+    /**
+     * Determines whether a literal or wildcard file has already been included that has a higher
+     * extension priority.
+     *
+     * @param file The path to the file.
+     * @param extensionPriority The priority of the extension.
+     * @param context The expansion context.
+     */
+    function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) {
+        var extensionPriority = ts.getExtensionPriority(file, extensions);
+        var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions);
+        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
+            var higherPriorityExtension = extensions[i];
+            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
+            if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    /**
+     * Removes files included via wildcard expansion with a lower extension priority that have
+     * already been included.
+     *
+     * @param file The path to the file.
+     * @param extensionPriority The priority of the extension.
+     * @param context The expansion context.
+     */
+    function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) {
+        var extensionPriority = ts.getExtensionPriority(file, extensions);
+        var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions);
+        for (var i = nextExtensionPriority; i < extensions.length; i++) {
+            var lowerPriorityExtension = extensions[i];
+            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
+            wildcardFiles.delete(lowerPriorityPath);
+        }
+    }
+    /**
+     * Gets a case sensitive key.
+     *
+     * @param key The original key.
+     */
+    function caseSensitiveKeyMapper(key) {
+        return key;
+    }
+    /**
+     * Gets a case insensitive key.
+     *
+     * @param key The original key.
+     */
+    function caseInsensitiveKeyMapper(key) {
+        return key.toLowerCase();
+    }
+    /**
+     * Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed.
+     * Also converts enum values back to strings.
+     */
+    /* @internal */
+    function convertCompilerOptionsForTelemetry(opts) {
+        var out = {};
+        for (var key in opts) {
+            if (opts.hasOwnProperty(key)) {
+                var type = getOptionFromName(key);
+                if (type !== undefined) {
+                    out[key] = getOptionValueWithEmptyStrings(opts[key], type);
+                }
+            }
+        }
+        return out;
+    }
+    ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry;
+    function getOptionValueWithEmptyStrings(value, option) {
+        switch (option.type) {
+            case "object":// "paths". Can't get any useful information from the value since we blank out strings, so just return "".
+                return "";
+            case "string":// Could be any arbitrary string -- use empty string instead.
+                return "";
+            case "number":// Allow numbers, but be sure to check it's actually a number.
+                return typeof value === "number" ? value : "";
+            case "boolean":
+                return typeof value === "boolean" ? value : "";
+            case "list":
+                var elementType_1 = option.element;
+                return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : "";
+            default:
+                return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) {
+                    if (optionEnumValue === value) {
+                        return optionStringValue;
+                    }
+                });
+        }
+    }
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+    var ScriptSnapshot;
+    (function (ScriptSnapshot) {
+        var StringScriptSnapshot = /** @class */ (function () {
+            function StringScriptSnapshot(text) {
+                this.text = text;
+            }
+            StringScriptSnapshot.prototype.getText = function (start, end) {
+                return start === 0 && end === this.text.length
+                    ? this.text
+                    : this.text.substring(start, end);
+            };
+            StringScriptSnapshot.prototype.getLength = function () {
+                return this.text.length;
+            };
+            StringScriptSnapshot.prototype.getChangeRange = function () {
+                // Text-based snapshots do not support incremental parsing. Return undefined
+                // to signal that to the caller.
+                return undefined;
+            };
+            return StringScriptSnapshot;
+        }());
+        function fromString(text) {
+            return new StringScriptSnapshot(text);
+        }
+        ScriptSnapshot.fromString = fromString;
+    })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {}));
+    var TextChange = /** @class */ (function () {
+        function TextChange() {
+        }
+        return TextChange;
+    }());
+    ts.TextChange = TextChange;
+    var HighlightSpanKind;
+    (function (HighlightSpanKind) {
+        HighlightSpanKind["none"] = "none";
+        HighlightSpanKind["definition"] = "definition";
+        HighlightSpanKind["reference"] = "reference";
+        HighlightSpanKind["writtenReference"] = "writtenReference";
+    })(HighlightSpanKind = ts.HighlightSpanKind || (ts.HighlightSpanKind = {}));
+    var IndentStyle;
+    (function (IndentStyle) {
+        IndentStyle[IndentStyle["None"] = 0] = "None";
+        IndentStyle[IndentStyle["Block"] = 1] = "Block";
+        IndentStyle[IndentStyle["Smart"] = 2] = "Smart";
+    })(IndentStyle = ts.IndentStyle || (ts.IndentStyle = {}));
+    var SymbolDisplayPartKind;
+    (function (SymbolDisplayPartKind) {
+        SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName";
+        SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral";
+    })(SymbolDisplayPartKind = ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
+    var OutputFileType;
+    (function (OutputFileType) {
+        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
+        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
+        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
+    })(OutputFileType = ts.OutputFileType || (ts.OutputFileType = {}));
+    var EndOfLineState;
+    (function (EndOfLineState) {
+        EndOfLineState[EndOfLineState["None"] = 0] = "None";
+        EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia";
+        EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral";
+        EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral";
+        EndOfLineState[EndOfLineState["InTemplateHeadOrNoSubstitutionTemplate"] = 4] = "InTemplateHeadOrNoSubstitutionTemplate";
+        EndOfLineState[EndOfLineState["InTemplateMiddleOrTail"] = 5] = "InTemplateMiddleOrTail";
+        EndOfLineState[EndOfLineState["InTemplateSubstitutionPosition"] = 6] = "InTemplateSubstitutionPosition";
+    })(EndOfLineState = ts.EndOfLineState || (ts.EndOfLineState = {}));
+    var TokenClass;
+    (function (TokenClass) {
+        TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation";
+        TokenClass[TokenClass["Keyword"] = 1] = "Keyword";
+        TokenClass[TokenClass["Operator"] = 2] = "Operator";
+        TokenClass[TokenClass["Comment"] = 3] = "Comment";
+        TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace";
+        TokenClass[TokenClass["Identifier"] = 5] = "Identifier";
+        TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral";
+        TokenClass[TokenClass["StringLiteral"] = 7] = "StringLiteral";
+        TokenClass[TokenClass["RegExpLiteral"] = 8] = "RegExpLiteral";
+    })(TokenClass = ts.TokenClass || (ts.TokenClass = {}));
+    var ScriptElementKind;
+    (function (ScriptElementKind) {
+        ScriptElementKind["unknown"] = "";
+        ScriptElementKind["warning"] = "warning";
+        /** predefined type (void) or keyword (class) */
+        ScriptElementKind["keyword"] = "keyword";
+        /** top level script node */
+        ScriptElementKind["scriptElement"] = "script";
+        /** module foo {} */
+        ScriptElementKind["moduleElement"] = "module";
+        /** class X {} */
+        ScriptElementKind["classElement"] = "class";
+        /** var x = class X {} */
+        ScriptElementKind["localClassElement"] = "local class";
+        /** interface Y {} */
+        ScriptElementKind["interfaceElement"] = "interface";
+        /** type T = ... */
+        ScriptElementKind["typeElement"] = "type";
+        /** enum E */
+        ScriptElementKind["enumElement"] = "enum";
+        ScriptElementKind["enumMemberElement"] = "enum member";
+        /**
+         * Inside module and script only
+         * const v = ..
+         */
+        ScriptElementKind["variableElement"] = "var";
+        /** Inside function */
+        ScriptElementKind["localVariableElement"] = "local var";
+        /**
+         * Inside module and script only
+         * function f() { }
+         */
+        ScriptElementKind["functionElement"] = "function";
+        /** Inside function */
+        ScriptElementKind["localFunctionElement"] = "local function";
+        /** class X { [public|private]* foo() {} } */
+        ScriptElementKind["memberFunctionElement"] = "method";
+        /** class X { [public|private]* [get|set] foo:number; } */
+        ScriptElementKind["memberGetAccessorElement"] = "getter";
+        ScriptElementKind["memberSetAccessorElement"] = "setter";
+        /**
+         * class X { [public|private]* foo:number; }
+         * interface Y { foo:number; }
+         */
+        ScriptElementKind["memberVariableElement"] = "property";
+        /** class X { constructor() { } } */
+        ScriptElementKind["constructorImplementationElement"] = "constructor";
+        /** interface Y { ():number; } */
+        ScriptElementKind["callSignatureElement"] = "call";
+        /** interface Y { []:number; } */
+        ScriptElementKind["indexSignatureElement"] = "index";
+        /** interface Y { new():Y; } */
+        ScriptElementKind["constructSignatureElement"] = "construct";
+        /** function foo(*Y*: string) */
+        ScriptElementKind["parameterElement"] = "parameter";
+        ScriptElementKind["typeParameterElement"] = "type parameter";
+        ScriptElementKind["primitiveType"] = "primitive type";
+        ScriptElementKind["label"] = "label";
+        ScriptElementKind["alias"] = "alias";
+        ScriptElementKind["constElement"] = "const";
+        ScriptElementKind["letElement"] = "let";
+        ScriptElementKind["directory"] = "directory";
+        ScriptElementKind["externalModuleName"] = "external module name";
+        /**
+         * <JsxTagName attribute1 attribute2={0} />
+         */
+        ScriptElementKind["jsxAttribute"] = "JSX attribute";
+    })(ScriptElementKind = ts.ScriptElementKind || (ts.ScriptElementKind = {}));
+    var ScriptElementKindModifier;
+    (function (ScriptElementKindModifier) {
+        ScriptElementKindModifier["none"] = "";
+        ScriptElementKindModifier["publicMemberModifier"] = "public";
+        ScriptElementKindModifier["privateMemberModifier"] = "private";
+        ScriptElementKindModifier["protectedMemberModifier"] = "protected";
+        ScriptElementKindModifier["exportedModifier"] = "export";
+        ScriptElementKindModifier["ambientModifier"] = "declare";
+        ScriptElementKindModifier["staticModifier"] = "static";
+        ScriptElementKindModifier["abstractModifier"] = "abstract";
+    })(ScriptElementKindModifier = ts.ScriptElementKindModifier || (ts.ScriptElementKindModifier = {}));
+    var ClassificationTypeNames;
+    (function (ClassificationTypeNames) {
+        ClassificationTypeNames["comment"] = "comment";
+        ClassificationTypeNames["identifier"] = "identifier";
+        ClassificationTypeNames["keyword"] = "keyword";
+        ClassificationTypeNames["numericLiteral"] = "number";
+        ClassificationTypeNames["operator"] = "operator";
+        ClassificationTypeNames["stringLiteral"] = "string";
+        ClassificationTypeNames["whiteSpace"] = "whitespace";
+        ClassificationTypeNames["text"] = "text";
+        ClassificationTypeNames["punctuation"] = "punctuation";
+        ClassificationTypeNames["className"] = "class name";
+        ClassificationTypeNames["enumName"] = "enum name";
+        ClassificationTypeNames["interfaceName"] = "interface name";
+        ClassificationTypeNames["moduleName"] = "module name";
+        ClassificationTypeNames["typeParameterName"] = "type parameter name";
+        ClassificationTypeNames["typeAliasName"] = "type alias name";
+        ClassificationTypeNames["parameterName"] = "parameter name";
+        ClassificationTypeNames["docCommentTagName"] = "doc comment tag name";
+        ClassificationTypeNames["jsxOpenTagName"] = "jsx open tag name";
+        ClassificationTypeNames["jsxCloseTagName"] = "jsx close tag name";
+        ClassificationTypeNames["jsxSelfClosingTagName"] = "jsx self closing tag name";
+        ClassificationTypeNames["jsxAttribute"] = "jsx attribute";
+        ClassificationTypeNames["jsxText"] = "jsx text";
+        ClassificationTypeNames["jsxAttributeStringLiteralValue"] = "jsx attribute string literal value";
+    })(ClassificationTypeNames = ts.ClassificationTypeNames || (ts.ClassificationTypeNames = {}));
+    var ClassificationType;
+    (function (ClassificationType) {
+        ClassificationType[ClassificationType["comment"] = 1] = "comment";
+        ClassificationType[ClassificationType["identifier"] = 2] = "identifier";
+        ClassificationType[ClassificationType["keyword"] = 3] = "keyword";
+        ClassificationType[ClassificationType["numericLiteral"] = 4] = "numericLiteral";
+        ClassificationType[ClassificationType["operator"] = 5] = "operator";
+        ClassificationType[ClassificationType["stringLiteral"] = 6] = "stringLiteral";
+        ClassificationType[ClassificationType["regularExpressionLiteral"] = 7] = "regularExpressionLiteral";
+        ClassificationType[ClassificationType["whiteSpace"] = 8] = "whiteSpace";
+        ClassificationType[ClassificationType["text"] = 9] = "text";
+        ClassificationType[ClassificationType["punctuation"] = 10] = "punctuation";
+        ClassificationType[ClassificationType["className"] = 11] = "className";
+        ClassificationType[ClassificationType["enumName"] = 12] = "enumName";
+        ClassificationType[ClassificationType["interfaceName"] = 13] = "interfaceName";
+        ClassificationType[ClassificationType["moduleName"] = 14] = "moduleName";
+        ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName";
+        ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
+        ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
+        ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
+        ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
+        ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
+        ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
+        ClassificationType[ClassificationType["jsxAttribute"] = 22] = "jsxAttribute";
+        ClassificationType[ClassificationType["jsxText"] = 23] = "jsxText";
+        ClassificationType[ClassificationType["jsxAttributeStringLiteralValue"] = 24] = "jsxAttributeStringLiteralValue";
+    })(ClassificationType = ts.ClassificationType || (ts.ClassificationType = {}));
+})(ts || (ts = {}));
+// These utilities are common to multiple language service features.
+/* @internal */
+var ts;
+(function (ts) {
+    ts.scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ true);
+    var SemanticMeaning;
+    (function (SemanticMeaning) {
+        SemanticMeaning[SemanticMeaning["None"] = 0] = "None";
+        SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value";
+        SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type";
+        SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace";
+        SemanticMeaning[SemanticMeaning["All"] = 7] = "All";
+    })(SemanticMeaning = ts.SemanticMeaning || (ts.SemanticMeaning = {}));
+    function getMeaningFromDeclaration(node) {
+        switch (node.kind) {
+            case 146 /* Parameter */:
+            case 226 /* VariableDeclaration */:
+            case 176 /* BindingElement */:
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+            case 261 /* PropertyAssignment */:
+            case 262 /* ShorthandPropertyAssignment */:
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 187 /* ArrowFunction */:
+            case 260 /* CatchClause */:
+            case 253 /* JsxAttribute */:
+                return 1 /* Value */;
+            case 145 /* TypeParameter */:
+            case 230 /* InterfaceDeclaration */:
+            case 231 /* TypeAliasDeclaration */:
+            case 163 /* TypeLiteral */:
+                return 2 /* Type */;
+            case 283 /* JSDocTypedefTag */:
+                // If it has no name node, it shares the name with the value declaration below it.
+                return node.name === undefined ? 1 /* Value */ | 2 /* Type */ : 2 /* Type */;
+            case 264 /* EnumMember */:
+            case 229 /* ClassDeclaration */:
+                return 1 /* Value */ | 2 /* Type */;
+            case 233 /* ModuleDeclaration */:
+                if (ts.isAmbientModule(node)) {
+                    return 4 /* Namespace */ | 1 /* Value */;
+                }
+                else if (ts.getModuleInstanceState(node) === 1 /* Instantiated */) {
+                    return 4 /* Namespace */ | 1 /* Value */;
+                }
+                else {
+                    return 4 /* Namespace */;
+                }
+            case 232 /* EnumDeclaration */:
+            case 241 /* NamedImports */:
+            case 242 /* ImportSpecifier */:
+            case 237 /* ImportEqualsDeclaration */:
+            case 238 /* ImportDeclaration */:
+            case 243 /* ExportAssignment */:
+            case 244 /* ExportDeclaration */:
+                return 7 /* All */;
+            // An external module can be a Value
+            case 265 /* SourceFile */:
+                return 4 /* Namespace */ | 1 /* Value */;
+        }
+        return 7 /* All */;
+    }
+    ts.getMeaningFromDeclaration = getMeaningFromDeclaration;
+    function getMeaningFromLocation(node) {
+        if (node.kind === 265 /* SourceFile */) {
+            return 1 /* Value */;
+        }
+        else if (node.parent.kind === 243 /* ExportAssignment */) {
+            return 7 /* All */;
+        }
+        else if (isInRightSideOfInternalImportEqualsDeclaration(node)) {
+            return getMeaningFromRightHandSideOfImportEquals(node);
+        }
+        else if (ts.isDeclarationName(node)) {
+            return getMeaningFromDeclaration(node.parent);
+        }
+        else if (isTypeReference(node)) {
+            return 2 /* Type */;
+        }
+        else if (isNamespaceReference(node)) {
+            return 4 /* Namespace */;
+        }
+        else if (ts.isTypeParameterDeclaration(node.parent)) {
+            ts.Debug.assert(ts.isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
+            return 2 /* Type */;
+        }
+        else {
+            return 1 /* Value */;
+        }
+    }
+    ts.getMeaningFromLocation = getMeaningFromLocation;
+    function getMeaningFromRightHandSideOfImportEquals(node) {
+        ts.Debug.assert(node.kind === 71 /* Identifier */);
+        //     import a = |b|; // Namespace
+        //     import a = |b.c|; // Value, type, namespace
+        //     import a = |b.c|.d; // Namespace
+        if (node.parent.kind === 143 /* QualifiedName */ &&
+            node.parent.right === node &&
+            node.parent.parent.kind === 237 /* ImportEqualsDeclaration */) {
+            return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
+        }
+        return 4 /* Namespace */;
+    }
+    function isInRightSideOfInternalImportEqualsDeclaration(node) {
+        while (node.parent.kind === 143 /* QualifiedName */) {
+            node = node.parent;
+        }
+        return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
+    }
+    ts.isInRightSideOfInternalImportEqualsDeclaration = isInRightSideOfInternalImportEqualsDeclaration;
+    function isNamespaceReference(node) {
+        return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
+    }
+    function isQualifiedNameNamespaceReference(node) {
+        var root = node;
+        var isLastClause = true;
+        if (root.parent.kind === 143 /* QualifiedName */) {
+            while (root.parent && root.parent.kind === 143 /* QualifiedName */) {
+                root = root.parent;
+            }
+            isLastClause = root.right === node;
+        }
+        return root.parent.kind === 159 /* TypeReference */ && !isLastClause;
+    }
+    function isPropertyAccessNamespaceReference(node) {
+        var root = node;
+        var isLastClause = true;
+        if (root.parent.kind === 179 /* PropertyAccessExpression */) {
+            while (root.parent && root.parent.kind === 179 /* PropertyAccessExpression */) {
+                root = root.parent;
+            }
+            isLastClause = root.name === node;
+        }
+        if (!isLastClause && root.parent.kind === 201 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 259 /* HeritageClause */) {
+            var decl = root.parent.parent.parent;
+            return (decl.kind === 229 /* ClassDeclaration */ && root.parent.parent.token === 108 /* ImplementsKeyword */) ||
+                (decl.kind === 230 /* InterfaceDeclaration */ && root.parent.parent.token === 85 /* ExtendsKeyword */);
+        }
+        return false;
+    }
+    function isTypeReference(node) {
+        if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
+            node = node.parent;
+        }
+        switch (node.kind) {
+            case 99 /* ThisKeyword */:
+                return !ts.isPartOfExpression(node);
+            case 169 /* ThisType */:
+                return true;
+        }
+        switch (node.parent.kind) {
+            case 159 /* TypeReference */:
+                return true;
+            case 201 /* ExpressionWithTypeArguments */:
+                return !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent);
+        }
+        return false;
+    }
+    function isCallExpressionTarget(node) {
+        return isCallOrNewExpressionTarget(node, 181 /* CallExpression */);
+    }
+    ts.isCallExpressionTarget = isCallExpressionTarget;
+    function isNewExpressionTarget(node) {
+        return isCallOrNewExpressionTarget(node, 182 /* NewExpression */);
+    }
+    ts.isNewExpressionTarget = isNewExpressionTarget;
+    function isCallOrNewExpressionTarget(node, kind) {
+        var target = climbPastPropertyAccess(node);
+        return target && target.parent && target.parent.kind === kind && target.parent.expression === target;
+    }
+    function climbPastPropertyAccess(node) {
+        return isRightSideOfPropertyAccess(node) ? node.parent : node;
+    }
+    ts.climbPastPropertyAccess = climbPastPropertyAccess;
+    function getTargetLabel(referenceNode, labelName) {
+        while (referenceNode) {
+            if (referenceNode.kind === 222 /* LabeledStatement */ && referenceNode.label.escapedText === labelName) {
+                return referenceNode.label;
+            }
+            referenceNode = referenceNode.parent;
+        }
+        return undefined;
+    }
+    ts.getTargetLabel = getTargetLabel;
+    function isJumpStatementTarget(node) {
+        return node.kind === 71 /* Identifier */ &&
+            (node.parent.kind === 218 /* BreakStatement */ || node.parent.kind === 217 /* ContinueStatement */) &&
+            node.parent.label === node;
+    }
+    ts.isJumpStatementTarget = isJumpStatementTarget;
+    function isLabelOfLabeledStatement(node) {
+        return node.kind === 71 /* Identifier */ &&
+            node.parent.kind === 222 /* LabeledStatement */ &&
+            node.parent.label === node;
+    }
+    function isLabelName(node) {
+        return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
+    }
+    ts.isLabelName = isLabelName;
+    function isRightSideOfQualifiedName(node) {
+        return node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node;
+    }
+    ts.isRightSideOfQualifiedName = isRightSideOfQualifiedName;
+    function isRightSideOfPropertyAccess(node) {
+        return node && node.parent && node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node;
+    }
+    ts.isRightSideOfPropertyAccess = isRightSideOfPropertyAccess;
+    function isNameOfModuleDeclaration(node) {
+        return node.parent.kind === 233 /* ModuleDeclaration */ && node.parent.name === node;
+    }
+    ts.isNameOfModuleDeclaration = isNameOfModuleDeclaration;
+    function isNameOfFunctionDeclaration(node) {
+        return node.kind === 71 /* Identifier */ &&
+            ts.isFunctionLike(node.parent) && node.parent.name === node;
+    }
+    ts.isNameOfFunctionDeclaration = isNameOfFunctionDeclaration;
+    function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
+        switch (node.parent.kind) {
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+            case 261 /* PropertyAssignment */:
+            case 264 /* EnumMember */:
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 233 /* ModuleDeclaration */:
+                return ts.getNameOfDeclaration(node.parent) === node;
+            case 180 /* ElementAccessExpression */:
+                return node.parent.argumentExpression === node;
+            case 144 /* ComputedPropertyName */:
+                return true;
+            case 173 /* LiteralType */:
+                return node.parent.parent.kind === 171 /* IndexedAccessType */;
+        }
+    }
+    ts.isLiteralNameOfPropertyDeclarationOrIndexAccess = isLiteralNameOfPropertyDeclarationOrIndexAccess;
+    function isExpressionOfExternalModuleImportEqualsDeclaration(node) {
+        return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
+            ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
+    }
+    ts.isExpressionOfExternalModuleImportEqualsDeclaration = isExpressionOfExternalModuleImportEqualsDeclaration;
+    function getContainerNode(node) {
+        if (node.kind === 283 /* JSDocTypedefTag */) {
+            // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope.
+            // node.parent = the JSDoc comment, node.parent.parent = the node having the comment.
+            // Then we get parent again in the loop.
+            node = node.parent.parent;
+        }
+        while (true) {
+            node = node.parent;
+            if (!node) {
+                return undefined;
+            }
+            switch (node.kind) {
+                case 265 /* SourceFile */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 229 /* ClassDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                case 232 /* EnumDeclaration */:
+                case 233 /* ModuleDeclaration */:
+                    return node;
+            }
+        }
+    }
+    ts.getContainerNode = getContainerNode;
+    function getNodeKind(node) {
+        switch (node.kind) {
+            case 265 /* SourceFile */:
+                return ts.isExternalModule(node) ? "module" /* moduleElement */ : "script" /* scriptElement */;
+            case 233 /* ModuleDeclaration */:
+                return "module" /* moduleElement */;
+            case 229 /* ClassDeclaration */:
+            case 199 /* ClassExpression */:
+                return "class" /* classElement */;
+            case 230 /* InterfaceDeclaration */: return "interface" /* interfaceElement */;
+            case 231 /* TypeAliasDeclaration */: return "type" /* typeElement */;
+            case 232 /* EnumDeclaration */: return "enum" /* enumElement */;
+            case 226 /* VariableDeclaration */:
+                return getKindOfVariableDeclaration(node);
+            case 176 /* BindingElement */:
+                return getKindOfVariableDeclaration(ts.getRootDeclaration(node));
+            case 187 /* ArrowFunction */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+                return "function" /* functionElement */;
+            case 153 /* GetAccessor */: return "getter" /* memberGetAccessorElement */;
+            case 154 /* SetAccessor */: return "setter" /* memberSetAccessorElement */;
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+                return "method" /* memberFunctionElement */;
+            case 149 /* PropertyDeclaration */:
+            case 148 /* PropertySignature */:
+                return "property" /* memberVariableElement */;
+            case 157 /* IndexSignature */: return "index" /* indexSignatureElement */;
+            case 156 /* ConstructSignature */: return "construct" /* constructSignatureElement */;
+            case 155 /* CallSignature */: return "call" /* callSignatureElement */;
+            case 152 /* Constructor */: return "constructor" /* constructorImplementationElement */;
+            case 145 /* TypeParameter */: return "type parameter" /* typeParameterElement */;
+            case 264 /* EnumMember */: return "enum member" /* enumMemberElement */;
+            case 146 /* Parameter */: return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) ? "property" /* memberVariableElement */ : "parameter" /* parameterElement */;
+            case 237 /* ImportEqualsDeclaration */:
+            case 242 /* ImportSpecifier */:
+            case 239 /* ImportClause */:
+            case 246 /* ExportSpecifier */:
+            case 240 /* NamespaceImport */:
+                return "alias" /* alias */;
+            case 283 /* JSDocTypedefTag */:
+                return "type" /* typeElement */;
+            case 194 /* BinaryExpression */:
+                var kind = ts.getSpecialPropertyAssignmentKind(node);
+                var right = node.right;
+                switch (kind) {
+                    case 0 /* None */:
+                        return "" /* unknown */;
+                    case 1 /* ExportsProperty */:
+                    case 2 /* ModuleExports */:
+                        var rightKind = getNodeKind(right);
+                        return rightKind === "" /* unknown */ ? "const" /* constElement */ : rightKind;
+                    case 3 /* PrototypeProperty */:
+                        return "method" /* memberFunctionElement */; // instance method
+                    case 4 /* ThisProperty */:
+                        return "property" /* memberVariableElement */; // property
+                    case 5 /* Property */:
+                        // static method / property
+                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
+                    default: {
+                        ts.assertTypeIsNever(kind);
+                        return "" /* unknown */;
+                    }
+                }
+            default:
+                return "" /* unknown */;
+        }
+        function getKindOfVariableDeclaration(v) {
+            return ts.isConst(v)
+                ? "const" /* constElement */
+                : ts.isLet(v)
+                    ? "let" /* letElement */
+                    : "var" /* variableElement */;
+        }
+    }
+    ts.getNodeKind = getNodeKind;
+    function isThis(node) {
+        switch (node.kind) {
+            case 99 /* ThisKeyword */:
+                // case SyntaxKind.ThisType: TODO: GH#9267
+                return true;
+            case 71 /* Identifier */:
+                // 'this' as a parameter
+                return ts.identifierIsThisKeyword(node) && node.parent.kind === 146 /* Parameter */;
+            default:
+                return false;
+        }
+    }
+    ts.isThis = isThis;
+    // Matches the beginning of a triple slash directive
+    var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
+    function getLineStartPositionForPosition(position, sourceFile) {
+        var lineStarts = ts.getLineStarts(sourceFile);
+        var line = sourceFile.getLineAndCharacterOfPosition(position).line;
+        return lineStarts[line];
+    }
+    ts.getLineStartPositionForPosition = getLineStartPositionForPosition;
+    function rangeContainsRange(r1, r2) {
+        return startEndContainsRange(r1.pos, r1.end, r2);
+    }
+    ts.rangeContainsRange = rangeContainsRange;
+    function startEndContainsRange(start, end, range) {
+        return start <= range.pos && end >= range.end;
+    }
+    ts.startEndContainsRange = startEndContainsRange;
+    function rangeContainsStartEnd(range, start, end) {
+        return range.pos <= start && range.end >= end;
+    }
+    ts.rangeContainsStartEnd = rangeContainsStartEnd;
+    function rangeOverlapsWithStartEnd(r1, start, end) {
+        return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
+    }
+    ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd;
+    function startEndOverlapsWithStartEnd(start1, end1, start2, end2) {
+        var start = Math.max(start1, start2);
+        var end = Math.min(end1, end2);
+        return start < end;
+    }
+    ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd;
+    /**
+     * Assumes `candidate.start <= position` holds.
+     */
+    function positionBelongsToNode(candidate, position, sourceFile) {
+        return position < candidate.end || !isCompletedNode(candidate, sourceFile);
+    }
+    ts.positionBelongsToNode = positionBelongsToNode;
+    function isCompletedNode(n, sourceFile) {
+        if (ts.nodeIsMissing(n)) {
+            return false;
+        }
+        switch (n.kind) {
+            case 229 /* ClassDeclaration */:
+            case 230 /* InterfaceDeclaration */:
+            case 232 /* EnumDeclaration */:
+            case 178 /* ObjectLiteralExpression */:
+            case 174 /* ObjectBindingPattern */:
+            case 163 /* TypeLiteral */:
+            case 207 /* Block */:
+            case 234 /* ModuleBlock */:
+            case 235 /* CaseBlock */:
+            case 241 /* NamedImports */:
+            case 245 /* NamedExports */:
+                return nodeEndsWith(n, 18 /* CloseBraceToken */, sourceFile);
+            case 260 /* CatchClause */:
+                return isCompletedNode(n.block, sourceFile);
+            case 182 /* NewExpression */:
+                if (!n.arguments) {
+                    return true;
+                }
+            // falls through
+            case 181 /* CallExpression */:
+            case 185 /* ParenthesizedExpression */:
+            case 168 /* ParenthesizedType */:
+                return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile);
+            case 160 /* FunctionType */:
+            case 161 /* ConstructorType */:
+                return isCompletedNode(n.type, sourceFile);
+            case 152 /* Constructor */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+            case 228 /* FunctionDeclaration */:
+            case 186 /* FunctionExpression */:
+            case 151 /* MethodDeclaration */:
+            case 150 /* MethodSignature */:
+            case 156 /* ConstructSignature */:
+            case 155 /* CallSignature */:
+            case 187 /* ArrowFunction */:
+                if (n.body) {
+                    return isCompletedNode(n.body, sourceFile);
+                }
+                if (n.type) {
+                    return isCompletedNode(n.type, sourceFile);
+                }
+                // Even though type parameters can be unclosed, we can get away with
+                // having at least a closing paren.
+                return hasChildOfKind(n, 20 /* CloseParenToken */, sourceFile);
+            case 233 /* ModuleDeclaration */:
+                return n.body && isCompletedNode(n.body, sourceFile);
+            case 211 /* IfStatement */:
+                if (n.elseStatement) {
+                    return isCompletedNode(n.elseStatement, sourceFile);
+                }
+                return isCompletedNode(n.thenStatement, sourceFile);
+            case 210 /* ExpressionStatement */:
+                return isCompletedNode(n.expression, sourceFile) ||
+                    hasChildOfKind(n, 25 /* SemicolonToken */);
+            case 177 /* ArrayLiteralExpression */:
+            case 175 /* ArrayBindingPattern */:
+            case 180 /* ElementAccessExpression */:
+            case 144 /* ComputedPropertyName */:
+            case 165 /* TupleType */:
+                return nodeEndsWith(n, 22 /* CloseBracketToken */, sourceFile);
+            case 157 /* IndexSignature */:
+                if (n.type) {
+                    return isCompletedNode(n.type, sourceFile);
+                }
+                return hasChildOfKind(n, 22 /* CloseBracketToken */, sourceFile);
+            case 257 /* CaseClause */:
+            case 258 /* DefaultClause */:
+                // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed
+                return false;
+            case 214 /* ForStatement */:
+            case 215 /* ForInStatement */:
+            case 216 /* ForOfStatement */:
+            case 213 /* WhileStatement */:
+                return isCompletedNode(n.statement, sourceFile);
+            case 212 /* DoStatement */:
+                // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
+                var hasWhileKeyword = findChildOfKind(n, 106 /* WhileKeyword */, sourceFile);
+                if (hasWhileKeyword) {
+                    return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile);
+                }
+                return isCompletedNode(n.statement, sourceFile);
+            case 162 /* TypeQuery */:
+                return isCompletedNode(n.exprName, sourceFile);
+            case 189 /* TypeOfExpression */:
+            case 188 /* DeleteExpression */:
+            case 190 /* VoidExpression */:
+            case 197 /* YieldExpression */:
+            case 198 /* SpreadElement */:
+                var unaryWordExpression = n;
+                return isCompletedNode(unaryWordExpression.expression, sourceFile);
+            case 183 /* TaggedTemplateExpression */:
+                return isCompletedNode(n.template, sourceFile);
+            case 196 /* TemplateExpression */:
+                var lastSpan = ts.lastOrUndefined(n.templateSpans);
+                return isCompletedNode(lastSpan, sourceFile);
+            case 205 /* TemplateSpan */:
+                return ts.nodeIsPresent(n.literal);
+            case 244 /* ExportDeclaration */:
+            case 238 /* ImportDeclaration */:
+                return ts.nodeIsPresent(n.moduleSpecifier);
+            case 192 /* PrefixUnaryExpression */:
+                return isCompletedNode(n.operand, sourceFile);
+            case 194 /* BinaryExpression */:
+                return isCompletedNode(n.right, sourceFile);
+            case 195 /* ConditionalExpression */:
+                return isCompletedNode(n.whenFalse, sourceFile);
+            default:
+                return true;
+        }
+    }
+    ts.isCompletedNode = isCompletedNode;
+    /*
+     * Checks if node ends with 'expectedLastToken'.
+     * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'.
+     */
+    function nodeEndsWith(n, expectedLastToken, sourceFile) {
+        var children = n.getChildren(sourceFile);
+        if (children.length) {
+            var last_2 = ts.lastOrUndefined(children);
+            if (last_2.kind === expectedLastToken) {
+                return true;
+            }
+            else if (last_2.kind === 25 /* SemicolonToken */ && children.length !== 1) {
+                return children[children.length - 2].kind === expectedLastToken;
+            }
+        }
+        return false;
+    }
+    function findListItemInfo(node) {
+        var list = findContainingList(node);
+        // It is possible at this point for syntaxList to be undefined, either if
+        // node.parent had no list child, or if none of its list children contained
+        // the span of node. If this happens, return undefined. The caller should
+        // handle this case.
+        if (!list) {
+            return undefined;
+        }
+        var children = list.getChildren();
+        var listItemIndex = ts.indexOfNode(children, node);
+        return {
+            listItemIndex: listItemIndex,
+            list: list
+        };
+    }
+    ts.findListItemInfo = findListItemInfo;
+    function hasChildOfKind(n, kind, sourceFile) {
+        return !!findChildOfKind(n, kind, sourceFile);
+    }
+    ts.hasChildOfKind = hasChildOfKind;
+    function findChildOfKind(n, kind, sourceFile) {
+        return ts.forEach(n.getChildren(sourceFile), function (c) { return c.kind === kind && c; });
+    }
+    ts.findChildOfKind = findChildOfKind;
+    function findContainingList(node) {
+        // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
+        // be parented by the container of the SyntaxList, not the SyntaxList itself.
+        // In order to find the list item index, we first need to locate SyntaxList itself and then search
+        // for the position of the relevant node (or comma).
+        var syntaxList = ts.forEach(node.parent.getChildren(), function (c) {
+            // find syntax list that covers the span of the node
+            if (ts.isSyntaxList(c) && c.pos <= node.pos && c.end >= node.end) {
+                return c;
+            }
+        });
+        // Either we didn't find an appropriate list, or the list must contain us.
+        ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node));
+        return syntaxList;
+    }
+    ts.findContainingList = findContainingList;
+    /* Gets the token whose text has range [start, end) and
+     * position >= start and (position < end or (position === end && token is keyword or identifier))
+     */
+    function getTouchingWord(sourceFile, position, includeJsDocComment) {
+        return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isWord(n.kind); });
+    }
+    ts.getTouchingWord = getTouchingWord;
+    /* Gets the token whose text has range [start, end) and position >= start
+     * and (position < end or (position === end && token is keyword or identifier or numeric/string literal))
+     */
+    function getTouchingPropertyName(sourceFile, position, includeJsDocComment) {
+        return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isPropertyName(n.kind); });
+    }
+    ts.getTouchingPropertyName = getTouchingPropertyName;
+    /**
+     * Returns the token if position is in [start, end).
+     * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true
+     */
+    function getTouchingToken(sourceFile, position, includeJsDocComment, includePrecedingTokenAtEndPosition) {
+        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false, includeJsDocComment);
+    }
+    ts.getTouchingToken = getTouchingToken;
+    /** Returns a token if position is in [start-of-leading-trivia, end) */
+    function getTokenAtPosition(sourceFile, position, includeJsDocComment, includeEndPosition) {
+        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, includeEndPosition, includeJsDocComment);
+    }
+    ts.getTokenAtPosition = getTokenAtPosition;
+    /** Get the token whose text contains the position */
+    function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition, includeJsDocComment) {
+        var current = sourceFile;
+        outer: while (true) {
+            if (ts.isToken(current)) {
+                // exit early
+                return current;
+            }
+            // find the child that contains 'position'
+            for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) {
+                var child = _a[_i];
+                if (!includeJsDocComment && ts.isJSDocNode(child)) {
+                    continue;
+                }
+                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment);
+                if (start > position) {
+                    // If this child begins after position, then all subsequent children will as well.
+                    break;
+                }
+                var end = child.getEnd();
+                if (position < end || (position === end && (child.kind === 1 /* EndOfFileToken */ || includeEndPosition))) {
+                    current = child;
+                    continue outer;
+                }
+                else if (includePrecedingTokenAtEndPosition && end === position) {
+                    var previousToken = findPrecedingToken(position, sourceFile, child);
+                    if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) {
+                        return previousToken;
+                    }
+                }
+            }
+            return current;
+        }
+    }
+    /**
+     * The token on the left of the position is the token that strictly includes the position
+     * or sits to the left of the cursor if it is on a boundary. For example
+     *
+     *   fo|o               -> will return foo
+     *   foo <comment> |bar -> will return foo
+     *
+     */
+    function findTokenOnLeftOfPosition(file, position) {
+        // Ideally, getTokenAtPosition should return a token. However, it is currently
+        // broken, so we do a check to make sure the result was indeed a token.
+        var tokenAtPosition = getTokenAtPosition(file, position, /*includeJsDocComment*/ false);
+        if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
+            return tokenAtPosition;
+        }
+        return findPrecedingToken(position, file);
+    }
+    ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition;
+    function findNextToken(previousToken, parent) {
+        return find(parent);
+        function find(n) {
+            if (ts.isToken(n) && n.pos === previousToken.end) {
+                // this is token that starts at the end of previous token - return it
+                return n;
+            }
+            var children = n.getChildren();
+            for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
+                var child = children_2[_i];
+                var shouldDiveInChildNode = 
+                // previous token is enclosed somewhere in the child
+                (child.pos <= previousToken.pos && child.end > previousToken.end) ||
+                    // previous token ends exactly at the beginning of child
+                    (child.pos === previousToken.end);
+                if (shouldDiveInChildNode && nodeHasTokens(child)) {
+                    return find(child);
+                }
+            }
+            return undefined;
+        }
+    }
+    ts.findNextToken = findNextToken;
+    /**
+     * Finds the rightmost token satisfying `token.end <= position`,
+     * excluding `JsxText` tokens containing only whitespace.
+     */
+    function findPrecedingToken(position, sourceFile, startNode, includeJsDoc) {
+        var result = find(startNode || sourceFile);
+        ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result)));
+        return result;
+        function findRightmostToken(n) {
+            if (ts.isToken(n)) {
+                return n;
+            }
+            var children = n.getChildren();
+            var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length);
+            return candidate && findRightmostToken(candidate);
+        }
+        function find(n) {
+            if (ts.isToken(n)) {
+                return n;
+            }
+            var children = n.getChildren();
+            for (var i = 0; i < children.length; i++) {
+                var child = children[i];
+                // Note that the span of a node's tokens is [node.getStart(...), node.end).
+                // Given that `position < child.end` and child has constituent tokens, we distinguish these cases:
+                // 1) `position` precedes `child`'s tokens or `child` has no tokens (ie: in a comment or whitespace preceding `child`):
+                // we need to find the last token in a previous child.
+                // 2) `position` is within the same span: we recurse on `child`.
+                if (position < child.end) {
+                    var start = child.getStart(sourceFile, includeJsDoc);
+                    var lookInPreviousChild = (start >= position) || // cursor in the leading trivia
+                        !nodeHasTokens(child) ||
+                        isWhiteSpaceOnlyJsxText(child);
+                    if (lookInPreviousChild) {
+                        // actual start of the node is past the position - previous token should be at the end of previous child
+                        var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i);
+                        return candidate && findRightmostToken(candidate);
+                    }
+                    else {
+                        // candidate should be in this node
+                        return find(child);
+                    }
+                }
+            }
+            ts.Debug.assert(startNode !== undefined || n.kind === 265 /* SourceFile */ || ts.isJSDocCommentContainingNode(n));
+            // Here we know that none of child token nodes embrace the position,
+            // the only known case is when position is at the end of the file.
+            // Try to find the rightmost token in the file without filtering.
+            // Namely we are skipping the check: 'position < node.end'
+            if (children.length) {
+                var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length);
+                return candidate && findRightmostToken(candidate);
+            }
+        }
+        /**
+         * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens.
+         */
+        function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) {
+            for (var i = exclusiveStartPosition - 1; i >= 0; i--) {
+                var child = children[i];
+                if (isWhiteSpaceOnlyJsxText(child)) {
+                    ts.Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`");
+                }
+                else if (nodeHasTokens(children[i])) {
+                    return children[i];
+                }
+            }
+        }
+    }
+    ts.findPrecedingToken = findPrecedingToken;
+    function isInString(sourceFile, position) {
+        var previousToken = findPrecedingToken(position, sourceFile);
+        if (previousToken && ts.isStringTextContainingNode(previousToken)) {
+            var start = previousToken.getStart();
+            var end = previousToken.getEnd();
+            // To be "in" one of these literals, the position has to be:
+            //   1. entirely within the token text.
+            //   2. at the end position of an unterminated token.
+            //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
+            if (start < position && position < end) {
+                return true;
+            }
+            if (position === end) {
+                return !!previousToken.isUnterminated;
+            }
+        }
+        return false;
+    }
+    ts.isInString = isInString;
+    /**
+     * returns true if the position is in between the open and close elements of an JSX expression.
+     */
+    function isInsideJsxElementOrAttribute(sourceFile, position) {
+        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+        if (!token) {
+            return false;
+        }
+        if (token.kind === 10 /* JsxText */) {
+            return true;
+        }
+        // <div>Hello |</div>
+        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 10 /* JsxText */) {
+            return true;
+        }
+        // <div> { | </div> or <div a={| </div>
+        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 256 /* JsxExpression */) {
+            return true;
+        }
+        // <div> {
+        // |
+        // } < /div>
+        if (token && token.kind === 18 /* CloseBraceToken */ && token.parent.kind === 256 /* JsxExpression */) {
+            return true;
+        }
+        // <div>|</div>
+        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 252 /* JsxClosingElement */) {
+            return true;
+        }
+        return false;
+    }
+    ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute;
+    function isWhiteSpaceOnlyJsxText(node) {
+        return ts.isJsxText(node) && node.containsOnlyWhiteSpaces;
+    }
+    ts.isWhiteSpaceOnlyJsxText = isWhiteSpaceOnlyJsxText;
+    function isInTemplateString(sourceFile, position) {
+        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+        return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
+    }
+    ts.isInTemplateString = isInTemplateString;
+    /**
+     * Returns true if the cursor at position in sourceFile is within a comment.
+     *
+     * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
+     * @param predicate Additional predicate to test on the comment range.
+     */
+    function isInComment(sourceFile, position, tokenAtPosition, predicate) {
+        return !!ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ false, /*precedingToken*/ undefined, tokenAtPosition, predicate);
+    }
+    ts.isInComment = isInComment;
+    function hasDocComment(sourceFile, position) {
+        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+        // First, we have to see if this position actually landed in a comment.
+        var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
+        return ts.forEach(commentRanges, jsDocPrefix);
+        function jsDocPrefix(c) {
+            var text = sourceFile.text;
+            return text.length >= c.pos + 3 && text[c.pos] === "/" && text[c.pos + 1] === "*" && text[c.pos + 2] === "*";
+        }
+    }
+    ts.hasDocComment = hasDocComment;
+    function nodeHasTokens(n) {
+        // If we have a token or node that has a non-zero width, it must have tokens.
+        // Note: getWidth() does not take trivia into account.
+        return n.getWidth() !== 0;
+    }
+    function getNodeModifiers(node) {
+        var flags = ts.getCombinedModifierFlags(node);
+        var result = [];
+        if (flags & 8 /* Private */)
+            result.push("private" /* privateMemberModifier */);
+        if (flags & 16 /* Protected */)
+            result.push("protected" /* protectedMemberModifier */);
+        if (flags & 4 /* Public */)
+            result.push("public" /* publicMemberModifier */);
+        if (flags & 32 /* Static */)
+            result.push("static" /* staticModifier */);
+        if (flags & 128 /* Abstract */)
+            result.push("abstract" /* abstractModifier */);
+        if (flags & 1 /* Export */)
+            result.push("export" /* exportedModifier */);
+        if (ts.isInAmbientContext(node))
+            result.push("declare" /* ambientModifier */);
+        return result.length > 0 ? result.join(",") : "" /* none */;
+    }
+    ts.getNodeModifiers = getNodeModifiers;
+    function getTypeArgumentOrTypeParameterList(node) {
+        if (node.kind === 159 /* TypeReference */ || node.kind === 181 /* CallExpression */) {
+            return node.typeArguments;
+        }
+        if (ts.isFunctionLike(node) || node.kind === 229 /* ClassDeclaration */ || node.kind === 230 /* InterfaceDeclaration */) {
+            return node.typeParameters;
+        }
+        return undefined;
+    }
+    ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
+    function isWord(kind) {
+        return kind === 71 /* Identifier */ || ts.isKeyword(kind);
+    }
+    ts.isWord = isWord;
+    function isPropertyName(kind) {
+        return kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */ || isWord(kind);
+    }
+    function isComment(kind) {
+        return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */;
+    }
+    ts.isComment = isComment;
+    function isStringOrRegularExpressionOrTemplateLiteral(kind) {
+        if (kind === 9 /* StringLiteral */
+            || kind === 12 /* RegularExpressionLiteral */
+            || ts.isTemplateLiteralKind(kind)) {
+            return true;
+        }
+        return false;
+    }
+    ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral;
+    function isPunctuation(kind) {
+        return 17 /* FirstPunctuation */ <= kind && kind <= 70 /* LastPunctuation */;
+    }
+    ts.isPunctuation = isPunctuation;
+    function isInsideTemplateLiteral(node, position) {
+        return ts.isTemplateLiteralKind(node.kind)
+            && (node.getStart() < position && position < node.getEnd()) || (!!node.isUnterminated && position === node.getEnd());
+    }
+    ts.isInsideTemplateLiteral = isInsideTemplateLiteral;
+    function isAccessibilityModifier(kind) {
+        switch (kind) {
+            case 114 /* PublicKeyword */:
+            case 112 /* PrivateKeyword */:
+            case 113 /* ProtectedKeyword */:
+                return true;
+        }
+        return false;
+    }
+    ts.isAccessibilityModifier = isAccessibilityModifier;
+    function cloneCompilerOptions(options) {
+        var result = ts.clone(options);
+        ts.setConfigFileInOptions(result, options && options.configFile);
+        return result;
+    }
+    ts.cloneCompilerOptions = cloneCompilerOptions;
+    function isArrayLiteralOrObjectLiteralDestructuringPattern(node) {
+        if (node.kind === 177 /* ArrayLiteralExpression */ ||
+            node.kind === 178 /* ObjectLiteralExpression */) {
+            // [a,b,c] from:
+            // [a, b, c] = someExpression;
+            if (node.parent.kind === 194 /* BinaryExpression */ &&
+                node.parent.left === node &&
+                node.parent.operatorToken.kind === 58 /* EqualsToken */) {
+                return true;
+            }
+            // [a, b, c] from:
+            // for([a, b, c] of expression)
+            if (node.parent.kind === 216 /* ForOfStatement */ &&
+                node.parent.initializer === node) {
+                return true;
+            }
+            // [a, b, c] of
+            // [x, [a, b, c] ] = someExpression
+            // or
+            // {x, a: {a, b, c} } = someExpression
+            if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === 261 /* PropertyAssignment */ ? node.parent.parent : node.parent)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern;
+    function hasTrailingDirectorySeparator(path) {
+        var lastCharacter = path.charAt(path.length - 1);
+        return lastCharacter === "/" || lastCharacter === "\\";
+    }
+    ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator;
+    function isInReferenceComment(sourceFile, position) {
+        return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) {
+            var commentText = sourceFile.text.substring(c.pos, c.end);
+            return tripleSlashDirectivePrefixRegex.test(commentText);
+        });
+    }
+    ts.isInReferenceComment = isInReferenceComment;
+    function isInNonReferenceComment(sourceFile, position) {
+        return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) {
+            var commentText = sourceFile.text.substring(c.pos, c.end);
+            return !tripleSlashDirectivePrefixRegex.test(commentText);
+        });
+    }
+    ts.isInNonReferenceComment = isInNonReferenceComment;
+    function createTextSpanFromNode(node, sourceFile) {
+        return ts.createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd());
+    }
+    ts.createTextSpanFromNode = createTextSpanFromNode;
+    function createTextSpanFromRange(range) {
+        return ts.createTextSpanFromBounds(range.pos, range.end);
+    }
+    ts.createTextSpanFromRange = createTextSpanFromRange;
+    function isTypeKeyword(kind) {
+        switch (kind) {
+            case 119 /* AnyKeyword */:
+            case 122 /* BooleanKeyword */:
+            case 130 /* NeverKeyword */:
+            case 133 /* NumberKeyword */:
+            case 134 /* ObjectKeyword */:
+            case 136 /* StringKeyword */:
+            case 137 /* SymbolKeyword */:
+            case 105 /* VoidKeyword */:
+                return true;
+            default:
+                return false;
+        }
+    }
+    ts.isTypeKeyword = isTypeKeyword;
+    /** True if the symbol is for an external module, as opposed to a namespace. */
+    function isExternalModuleSymbol(moduleSymbol) {
+        ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
+        return moduleSymbol.name.charCodeAt(0) === 34 /* doubleQuote */;
+    }
+    ts.isExternalModuleSymbol = isExternalModuleSymbol;
+    /** Returns `true` the first time it encounters a node and `false` afterwards. */
+    function nodeSeenTracker() {
+        var seen = [];
+        return function (node) {
+            var id = ts.getNodeId(node);
+            return !seen[id] && (seen[id] = true);
+        };
+    }
+    ts.nodeSeenTracker = nodeSeenTracker;
+})(ts || (ts = {}));
+// Display-part writer helpers
+/* @internal */
+(function (ts) {
+    function isFirstDeclarationOfSymbolParameter(symbol) {
+        return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 146 /* Parameter */;
+    }
+    ts.isFirstDeclarationOfSymbolParameter = isFirstDeclarationOfSymbolParameter;
+    var displayPartWriter = getDisplayPartWriter();
+    function getDisplayPartWriter() {
+        var displayParts;
+        var lineStart;
+        var indent;
+        resetWriter();
+        return {
+            displayParts: function () { return displayParts; },
+            writeKeyword: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.keyword); },
+            writeOperator: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.operator); },
+            writePunctuation: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
+            writeSpace: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.space); },
+            writeStringLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
+            writeParameter: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.parameterName); },
+            writeProperty: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.propertyName); },
+            writeSymbol: writeSymbol,
+            writeLine: writeLine,
+            increaseIndent: function () { indent++; },
+            decreaseIndent: function () { indent--; },
+            clear: resetWriter,
+            trackSymbol: ts.noop,
+            reportInaccessibleThisError: ts.noop,
+            reportPrivateInBaseOfClassExpression: ts.noop,
+        };
+        function writeIndent() {
+            if (lineStart) {
+                var indentString = ts.getIndentString(indent);
+                if (indentString) {
+                    displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space));
+                }
+                lineStart = false;
+            }
+        }
+        function writeKind(text, kind) {
+            writeIndent();
+            displayParts.push(displayPart(text, kind));
+        }
+        function writeSymbol(text, symbol) {
+            writeIndent();
+            displayParts.push(symbolPart(text, symbol));
+        }
+        function writeLine() {
+            displayParts.push(lineBreakPart());
+            lineStart = true;
+        }
+        function resetWriter() {
+            displayParts = [];
+            lineStart = true;
+            indent = 0;
+        }
+    }
+    function symbolPart(text, symbol) {
+        return displayPart(text, displayPartKind(symbol));
+        function displayPartKind(symbol) {
+            var flags = symbol.flags;
+            if (flags & 3 /* Variable */) {
+                return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName;
+            }
+            else if (flags & 4 /* Property */) {
+                return ts.SymbolDisplayPartKind.propertyName;
+            }
+            else if (flags & 32768 /* GetAccessor */) {
+                return ts.SymbolDisplayPartKind.propertyName;
+            }
+            else if (flags & 65536 /* SetAccessor */) {
+                return ts.SymbolDisplayPartKind.propertyName;
+            }
+            else if (flags & 8 /* EnumMember */) {
+                return ts.SymbolDisplayPartKind.enumMemberName;
+            }
+            else if (flags & 16 /* Function */) {
+                return ts.SymbolDisplayPartKind.functionName;
+            }
+            else if (flags & 32 /* Class */) {
+                return ts.SymbolDisplayPartKind.className;
+            }
+            else if (flags & 64 /* Interface */) {
+                return ts.SymbolDisplayPartKind.interfaceName;
+            }
+            else if (flags & 384 /* Enum */) {
+                return ts.SymbolDisplayPartKind.enumName;
+            }
+            else if (flags & 1536 /* Module */) {
+                return ts.SymbolDisplayPartKind.moduleName;
+            }
+            else if (flags & 8192 /* Method */) {
+                return ts.SymbolDisplayPartKind.methodName;
+            }
+            else if (flags & 262144 /* TypeParameter */) {
+                return ts.SymbolDisplayPartKind.typeParameterName;
+            }
+            else if (flags & 524288 /* TypeAlias */) {
+                return ts.SymbolDisplayPartKind.aliasName;
+            }
+            else if (flags & 2097152 /* Alias */) {
+                return ts.SymbolDisplayPartKind.aliasName;
+            }
+            return ts.SymbolDisplayPartKind.text;
+        }
+    }
+    ts.symbolPart = symbolPart;
+    function displayPart(text, kind) {
+        return { text: text, kind: ts.SymbolDisplayPartKind[kind] };
+    }
+    ts.displayPart = displayPart;
+    function spacePart() {
+        return displayPart(" ", ts.SymbolDisplayPartKind.space);
+    }
+    ts.spacePart = spacePart;
+    function keywordPart(kind) {
+        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.keyword);
+    }
+    ts.keywordPart = keywordPart;
+    function punctuationPart(kind) {
+        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.punctuation);
+    }
+    ts.punctuationPart = punctuationPart;
+    function operatorPart(kind) {
+        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.operator);
+    }
+    ts.operatorPart = operatorPart;
+    function textOrKeywordPart(text) {
+        var kind = ts.stringToToken(text);
+        return kind === undefined
+            ? textPart(text)
+            : keywordPart(kind);
+    }
+    ts.textOrKeywordPart = textOrKeywordPart;
+    function textPart(text) {
+        return displayPart(text, ts.SymbolDisplayPartKind.text);
+    }
+    ts.textPart = textPart;
+    var carriageReturnLineFeed = "\r\n";
+    /**
+     * The default is CRLF.
+     */
+    function getNewLineOrDefaultFromHost(host) {
+        return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
+    }
+    ts.getNewLineOrDefaultFromHost = getNewLineOrDefaultFromHost;
+    function lineBreakPart() {
+        return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak);
+    }
+    ts.lineBreakPart = lineBreakPart;
+    function mapToDisplayParts(writeDisplayParts) {
+        try {
+            writeDisplayParts(displayPartWriter);
+            return displayPartWriter.displayParts();
+        }
+        finally {
+            displayPartWriter.clear();
+        }
+    }
+    ts.mapToDisplayParts = mapToDisplayParts;
+    function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) {
+        return mapToDisplayParts(function (writer) {
+            typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
+        });
+    }
+    ts.typeToDisplayParts = typeToDisplayParts;
+    function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) {
+        return mapToDisplayParts(function (writer) {
+            typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags);
+        });
+    }
+    ts.symbolToDisplayParts = symbolToDisplayParts;
+    function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) {
+        flags |= 65536 /* UseAliasDefinedOutsideCurrentScope */;
+        return mapToDisplayParts(function (writer) {
+            typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
+        });
+    }
+    ts.signatureToDisplayParts = signatureToDisplayParts;
+    function getDeclaredName(typeChecker, symbol, location) {
+        // If this is an export or import specifier it could have been renamed using the 'as' syntax.
+        // If so we want to search for whatever is under the cursor.
+        if (isImportOrExportSpecifierName(location) || ts.isStringOrNumericLiteral(location) && location.parent.kind === 144 /* ComputedPropertyName */) {
+            return ts.getTextOfIdentifierOrLiteral(location);
+        }
+        // Try to get the local symbol if we're dealing with an 'export default'
+        // since that symbol has the "true" name.
+        var localExportDefaultSymbol = ts.getLocalSymbolForExportDefault(symbol);
+        return typeChecker.symbolToString(localExportDefaultSymbol || symbol);
+    }
+    ts.getDeclaredName = getDeclaredName;
+    function isImportOrExportSpecifierName(location) {
+        return location.parent &&
+            (location.parent.kind === 242 /* ImportSpecifier */ || location.parent.kind === 246 /* ExportSpecifier */) &&
+            location.parent.propertyName === location;
+    }
+    ts.isImportOrExportSpecifierName = isImportOrExportSpecifierName;
+    /**
+     * Strip off existed single quotes or double quotes from a given string
+     *
+     * @return non-quoted string
+     */
+    function stripQuotes(name) {
+        var length = name.length;
+        if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && ts.isSingleOrDoubleQuote(name.charCodeAt(0))) {
+            return name.substring(1, length - 1);
+        }
+        return name;
+    }
+    ts.stripQuotes = stripQuotes;
+    function scriptKindIs(fileName, host) {
+        var scriptKinds = [];
+        for (var _i = 2; _i < arguments.length; _i++) {
+            scriptKinds[_i - 2] = arguments[_i];
+        }
+        var scriptKind = getScriptKind(fileName, host);
+        return ts.forEach(scriptKinds, function (k) { return k === scriptKind; });
+    }
+    ts.scriptKindIs = scriptKindIs;
+    function getScriptKind(fileName, host) {
+        // First check to see if the script kind was specified by the host. Chances are the host
+        // may override the default script kind for the file extension.
+        return ts.ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName));
+    }
+    ts.getScriptKind = getScriptKind;
+    function getUniqueSymbolId(symbol, checker) {
+        return ts.getSymbolId(ts.skipAlias(symbol, checker));
+    }
+    ts.getUniqueSymbolId = getUniqueSymbolId;
+    function getFirstNonSpaceCharacterPosition(text, position) {
+        while (ts.isWhiteSpaceLike(text.charCodeAt(position))) {
+            position += 1;
+        }
+        return position;
+    }
+    ts.getFirstNonSpaceCharacterPosition = getFirstNonSpaceCharacterPosition;
+    function getOpenBrace(constructor, sourceFile) {
+        // First token is the open curly, this is where we want to put the 'super' call.
+        return constructor.body.getFirstToken(sourceFile);
+    }
+    ts.getOpenBrace = getOpenBrace;
+    function getOpenBraceOfClassLike(declaration, sourceFile) {
+        return ts.getTokenAtPosition(sourceFile, declaration.members.pos - 1, /*includeJsDocComment*/ false);
+    }
+    ts.getOpenBraceOfClassLike = getOpenBraceOfClassLike;
+    function getSourceFileImportLocation(node) {
+        // For a source file, it is possible there are detached comments we should not skip
+        var text = node.text;
+        var ranges = ts.getLeadingCommentRanges(text, 0);
+        if (!ranges)
+            return 0;
+        var position = 0;
+        // However we should still skip a pinned comment at the top
+        if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0])) {
+            position = ranges[0].end + 1;
+            ranges = ranges.slice(1);
+        }
+        // As well as any triple slash references
+        for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) {
+            var range = ranges_1[_i];
+            if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) {
+                position = range.end + 1;
+                continue;
+            }
+            break;
+        }
+        return position;
+    }
+    ts.getSourceFileImportLocation = getSourceFileImportLocation;
+    /**
+     * Creates a deep, memberwise clone of a node with no source map location.
+     *
+     * WARNING: This is an expensive operation and is only intended to be used in refactorings
+     * and code fixes (because those are triggered by explicit user actions).
+     */
+    function getSynthesizedDeepClone(node) {
+        if (node === undefined) {
+            return undefined;
+        }
+        var visited = ts.visitEachChild(node, getSynthesizedDeepClone, ts.nullTransformationContext);
+        if (visited === node) {
+            // This only happens for leaf nodes - internal nodes always see their children change.
+            var clone_7 = ts.getSynthesizedClone(node);
+            if (ts.isStringLiteral(clone_7)) {
+                clone_7.textSourceNode = node;
+            }
+            else if (ts.isNumericLiteral(clone_7)) {
+                clone_7.numericLiteralFlags = node.numericLiteralFlags;
+            }
+            clone_7.pos = node.pos;
+            clone_7.end = node.end;
+            return clone_7;
+        }
+        // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update
+        // the new node created by visitEachChild with the extra changes getSynthesizedClone
+        // would have made.
+        visited.parent = undefined;
+        return visited;
+    }
+    ts.getSynthesizedDeepClone = getSynthesizedDeepClone;
+    /**
+     * Sets EmitFlags to suppress leading and trailing trivia on the node.
+     */
+    /* @internal */
+    function suppressLeadingAndTrailingTrivia(node) {
+        ts.Debug.assert(node !== undefined);
+        suppressLeading(node);
+        suppressTrailing(node);
+        function suppressLeading(node) {
+            ts.addEmitFlags(node, 512 /* NoLeadingComments */);
+            var firstChild = ts.forEachChild(node, function (child) { return child; });
+            firstChild && suppressLeading(firstChild);
+        }
+        function suppressTrailing(node) {
+            ts.addEmitFlags(node, 1024 /* NoTrailingComments */);
+            var lastChild = undefined;
+            ts.forEachChild(node, function (child) { return (lastChild = child, undefined); }, function (children) {
+                // As an optimization, jump straight to the end of the list.
+                if (children.length) {
+                    lastChild = ts.last(children);
+                }
+                return undefined;
+            });
+            lastChild && suppressTrailing(lastChild);
+        }
+    }
+    ts.suppressLeadingAndTrailingTrivia = suppressLeadingAndTrailingTrivia;
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+    /// Classifier
+    function createClassifier() {
+        var scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false);
+        /// We do not have a full parser support to know when we should parse a regex or not
+        /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
+        /// we have a series of divide operator. this list allows us to be more accurate by ruling out
+        /// locations where a regexp cannot exist.
+        var noRegexTable = [];
+        noRegexTable[71 /* Identifier */] = true;
+        noRegexTable[9 /* StringLiteral */] = true;
+        noRegexTable[8 /* NumericLiteral */] = true;
+        noRegexTable[12 /* RegularExpressionLiteral */] = true;
+        noRegexTable[99 /* ThisKeyword */] = true;
+        noRegexTable[43 /* PlusPlusToken */] = true;
+        noRegexTable[44 /* MinusMinusToken */] = true;
+        noRegexTable[20 /* CloseParenToken */] = true;
+        noRegexTable[22 /* CloseBracketToken */] = true;
+        noRegexTable[18 /* CloseBraceToken */] = true;
+        noRegexTable[101 /* TrueKeyword */] = true;
+        noRegexTable[86 /* FalseKeyword */] = true;
+        // Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
+        // classification on template strings. Because of the context free nature of templates,
+        // the only precise way to classify a template portion would be by propagating the stack across
+        // lines, just as we do with the end-of-line state. However, this is a burden for implementers,
+        // and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
+        // flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
+        // Situations in which this fails are
+        //  1) When template strings are nested across different lines:
+        //          `hello ${ `world
+        //          ` }`
+        //
+        //     Where on the second line, you will get the closing of a template,
+        //     a closing curly, and a new template.
+        //
+        //  2) When substitution expressions have curly braces and the curly brace falls on the next line:
+        //          `hello ${ () => {
+        //          return "world" } } `
+        //
+        //     Where on the second line, you will get the 'return' keyword,
+        //     a string literal, and a template end consisting of '} } `'.
+        var templateStack = [];
+        /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
+        function canFollow(keyword1, keyword2) {
+            if (ts.isAccessibilityModifier(keyword1)) {
+                if (keyword2 === 125 /* GetKeyword */ ||
+                    keyword2 === 135 /* SetKeyword */ ||
+                    keyword2 === 123 /* ConstructorKeyword */ ||
+                    keyword2 === 115 /* StaticKeyword */) {
+                    // Allow things like "public get", "public constructor" and "public static".
+                    // These are all legal.
+                    return true;
+                }
+                // Any other keyword following "public" is actually an identifier an not a real
+                // keyword.
+                return false;
+            }
+            // Assume any other keyword combination is legal.  This can be refined in the future
+            // if there are more cases we want the classifier to be better at.
+            return true;
+        }
+        function convertClassifications(classifications, text) {
+            var entries = [];
+            var dense = classifications.spans;
+            var lastEnd = 0;
+            for (var i = 0; i < dense.length; i += 3) {
+                var start = dense[i];
+                var length_6 = dense[i + 1];
+                var type = dense[i + 2];
+                // Make a whitespace entry between the last item and this one.
+                if (lastEnd >= 0) {
+                    var whitespaceLength_1 = start - lastEnd;
+                    if (whitespaceLength_1 > 0) {
+                        entries.push({ length: whitespaceLength_1, classification: ts.TokenClass.Whitespace });
+                    }
+                }
+                entries.push({ length: length_6, classification: convertClassification(type) });
+                lastEnd = start + length_6;
+            }
+            var whitespaceLength = text.length - lastEnd;
+            if (whitespaceLength > 0) {
+                entries.push({ length: whitespaceLength, classification: ts.TokenClass.Whitespace });
+            }
+            return { entries: entries, finalLexState: classifications.endOfLineState };
+        }
+        function convertClassification(type) {
+            switch (type) {
+                case 1 /* comment */: return ts.TokenClass.Comment;
+                case 3 /* keyword */: return ts.TokenClass.Keyword;
+                case 4 /* numericLiteral */: return ts.TokenClass.NumberLiteral;
+                case 5 /* operator */: return ts.TokenClass.Operator;
+                case 6 /* stringLiteral */: return ts.TokenClass.StringLiteral;
+                case 8 /* whiteSpace */: return ts.TokenClass.Whitespace;
+                case 10 /* punctuation */: return ts.TokenClass.Punctuation;
+                case 2 /* identifier */:
+                case 11 /* className */:
+                case 12 /* enumName */:
+                case 13 /* interfaceName */:
+                case 14 /* moduleName */:
+                case 15 /* typeParameterName */:
+                case 16 /* typeAliasName */:
+                case 9 /* text */:
+                case 17 /* parameterName */:
+                default:
+                    return ts.TokenClass.Identifier;
+            }
+        }
+        function getClassificationsForLine(text, lexState, syntacticClassifierAbsent) {
+            return convertClassifications(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
+        }
+        // If there is a syntactic classifier ('syntacticClassifierAbsent' is false),
+        // we will be more conservative in order to avoid conflicting with the syntactic classifier.
+        function getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent) {
+            var offset = 0;
+            var token = 0 /* Unknown */;
+            var lastNonTriviaToken = 0 /* Unknown */;
+            // Empty out the template stack for reuse.
+            while (templateStack.length > 0) {
+                templateStack.pop();
+            }
+            // If we're in a string literal, then prepend: "\
+            // (and a newline).  That way when we lex we'll think we're still in a string literal.
+            //
+            // If we're in a multiline comment, then prepend: /*
+            // (and a newline).  That way when we lex we'll think we're still in a multiline comment.
+            switch (lexState) {
+                case 3 /* InDoubleQuoteStringLiteral */:
+                    text = "\"\\\n" + text;
+                    offset = 3;
+                    break;
+                case 2 /* InSingleQuoteStringLiteral */:
+                    text = "'\\\n" + text;
+                    offset = 3;
+                    break;
+                case 1 /* InMultiLineCommentTrivia */:
+                    text = "/*\n" + text;
+                    offset = 3;
+                    break;
+                case 4 /* InTemplateHeadOrNoSubstitutionTemplate */:
+                    text = "`\n" + text;
+                    offset = 2;
+                    break;
+                case 5 /* InTemplateMiddleOrTail */:
+                    text = "}\n" + text;
+                    offset = 2;
+                // falls through
+                case 6 /* InTemplateSubstitutionPosition */:
+                    templateStack.push(14 /* TemplateHead */);
+                    break;
+            }
+            scanner.setText(text);
+            var result = {
+                endOfLineState: 0 /* None */,
+                spans: []
+            };
+            // We can run into an unfortunate interaction between the lexical and syntactic classifier
+            // when the user is typing something generic.  Consider the case where the user types:
+            //
+            //      Foo<number
+            //
+            // From the lexical classifier's perspective, 'number' is a keyword, and so the word will
+            // be classified as such.  However, from the syntactic classifier's tree-based perspective
+            // this is simply an expression with the identifier 'number' on the RHS of the less than
+            // token.  So the classification will go back to being an identifier.  The moment the user
+            // types again, number will become a keyword, then an identifier, etc. etc.
+            //
+            // To try to avoid this problem, we avoid classifying contextual keywords as keywords
+            // when the user is potentially typing something generic.  We just can't do a good enough
+            // job at the lexical level, and so well leave it up to the syntactic classifier to make
+            // the determination.
+            //
+            // In order to determine if the user is potentially typing something generic, we use a
+            // weak heuristic where we track < and > tokens.  It's a weak heuristic, but should
+            // work well enough in practice.
+            var angleBracketStack = 0;
+            do {
+                token = scanner.scan();
+                if (!ts.isTrivia(token)) {
+                    if ((token === 41 /* SlashToken */ || token === 63 /* SlashEqualsToken */) && !noRegexTable[lastNonTriviaToken]) {
+                        if (scanner.reScanSlashToken() === 12 /* RegularExpressionLiteral */) {
+                            token = 12 /* RegularExpressionLiteral */;
+                        }
+                    }
+                    else if (lastNonTriviaToken === 23 /* DotToken */ && isKeyword(token)) {
+                        token = 71 /* Identifier */;
+                    }
+                    else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
+                        // We have two keywords in a row.  Only treat the second as a keyword if
+                        // it's a sequence that could legally occur in the language.  Otherwise
+                        // treat it as an identifier.  This way, if someone writes "private var"
+                        // we recognize that 'var' is actually an identifier here.
+                        token = 71 /* Identifier */;
+                    }
+                    else if (lastNonTriviaToken === 71 /* Identifier */ &&
+                        token === 27 /* LessThanToken */) {
+                        // Could be the start of something generic.  Keep track of that by bumping
+                        // up the current count of generic contexts we may be in.
+                        angleBracketStack++;
+                    }
+                    else if (token === 29 /* GreaterThanToken */ && angleBracketStack > 0) {
+                        // If we think we're currently in something generic, then mark that that
+                        // generic entity is complete.
+                        angleBracketStack--;
+                    }
+                    else if (token === 119 /* AnyKeyword */ ||
+                        token === 136 /* StringKeyword */ ||
+                        token === 133 /* NumberKeyword */ ||
+                        token === 122 /* BooleanKeyword */ ||
+                        token === 137 /* SymbolKeyword */) {
+                        if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
+                            // If it looks like we're could be in something generic, don't classify this
+                            // as a keyword.  We may just get overwritten by the syntactic classifier,
+                            // causing a noisy experience for the user.
+                            token = 71 /* Identifier */;
+                        }
+                    }
+                    else if (token === 14 /* TemplateHead */) {
+                        templateStack.push(token);
+                    }
+                    else if (token === 17 /* OpenBraceToken */) {
+                        // If we don't have anything on the template stack,
+                        // then we aren't trying to keep track of a previously scanned template head.
+                        if (templateStack.length > 0) {
+                            templateStack.push(token);
+                        }
+                    }
+                    else if (token === 18 /* CloseBraceToken */) {
+                        // If we don't have anything on the template stack,
+                        // then we aren't trying to keep track of a previously scanned template head.
+                        if (templateStack.length > 0) {
+                            var lastTemplateStackToken = ts.lastOrUndefined(templateStack);
+                            if (lastTemplateStackToken === 14 /* TemplateHead */) {
+                                token = scanner.reScanTemplateToken();
+                                // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
+                                if (token === 16 /* TemplateTail */) {
+                                    templateStack.pop();
+                                }
+                                else {
+                                    ts.Debug.assertEqual(token, 15 /* TemplateMiddle */, "Should have been a template middle.");
+                                }
+                            }
+                            else {
+                                ts.Debug.assertEqual(lastTemplateStackToken, 17 /* OpenBraceToken */, "Should have been an open brace");
+                                templateStack.pop();
+                            }
+                        }
+                    }
+                    lastNonTriviaToken = token;
+                }
+                processToken();
+            } while (token !== 1 /* EndOfFileToken */);
+            return result;
+            function processToken() {
+                var start = scanner.getTokenPos();
+                var end = scanner.getTextPos();
+                addResult(start, end, classFromKind(token));
+                if (end >= text.length) {
+                    if (token === 9 /* StringLiteral */) {
+                        // Check to see if we finished up on a multiline string literal.
+                        var tokenText = scanner.getTokenText();
+                        if (scanner.isUnterminated()) {
+                            var lastCharIndex = tokenText.length - 1;
+                            var numBackslashes = 0;
+                            while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === 92 /* backslash */) {
+                                numBackslashes++;
+                            }
+                            // If we have an odd number of backslashes, then the multiline string is unclosed
+                            if (numBackslashes & 1) {
+                                var quoteChar = tokenText.charCodeAt(0);
+                                result.endOfLineState = quoteChar === 34 /* doubleQuote */
+                                    ? 3 /* InDoubleQuoteStringLiteral */
+                                    : 2 /* InSingleQuoteStringLiteral */;
+                            }
+                        }
+                    }
+                    else if (token === 3 /* MultiLineCommentTrivia */) {
+                        // Check to see if the multiline comment was unclosed.
+                        if (scanner.isUnterminated()) {
+                            result.endOfLineState = 1 /* InMultiLineCommentTrivia */;
+                        }
+                    }
+                    else if (ts.isTemplateLiteralKind(token)) {
+                        if (scanner.isUnterminated()) {
+                            if (token === 16 /* TemplateTail */) {
+                                result.endOfLineState = 5 /* InTemplateMiddleOrTail */;
+                            }
+                            else if (token === 13 /* NoSubstitutionTemplateLiteral */) {
+                                result.endOfLineState = 4 /* InTemplateHeadOrNoSubstitutionTemplate */;
+                            }
+                            else {
+                                ts.Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
+                            }
+                        }
+                    }
+                    else if (templateStack.length > 0 && ts.lastOrUndefined(templateStack) === 14 /* TemplateHead */) {
+                        result.endOfLineState = 6 /* InTemplateSubstitutionPosition */;
+                    }
+                }
+            }
+            function addResult(start, end, classification) {
+                if (classification === 8 /* whiteSpace */) {
+                    // Don't bother with whitespace classifications.  They're not needed.
+                    return;
+                }
+                if (start === 0 && offset > 0) {
+                    // We're classifying the first token, and this was a case where we prepended
+                    // text.  We should consider the start of this token to be at the start of
+                    // the original text.
+                    start += offset;
+                }
+                // All our tokens are in relation to the augmented text.  Move them back to be
+                // relative to the original text.
+                start -= offset;
+                end -= offset;
+                var length = end - start;
+                if (length > 0) {
+                    result.spans.push(start);
+                    result.spans.push(length);
+                    result.spans.push(classification);
+                }
+            }
+        }
+        function isBinaryExpressionOperatorToken(token) {
+            switch (token) {
+                case 39 /* AsteriskToken */:
+                case 41 /* SlashToken */:
+                case 42 /* PercentToken */:
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 45 /* LessThanLessThanToken */:
+                case 46 /* GreaterThanGreaterThanToken */:
+                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                case 27 /* LessThanToken */:
+                case 29 /* GreaterThanToken */:
+                case 30 /* LessThanEqualsToken */:
+                case 31 /* GreaterThanEqualsToken */:
+                case 93 /* InstanceOfKeyword */:
+                case 92 /* InKeyword */:
+                case 118 /* AsKeyword */:
+                case 32 /* EqualsEqualsToken */:
+                case 33 /* ExclamationEqualsToken */:
+                case 34 /* EqualsEqualsEqualsToken */:
+                case 35 /* ExclamationEqualsEqualsToken */:
+                case 48 /* AmpersandToken */:
+                case 50 /* CaretToken */:
+                case 49 /* BarToken */:
+                case 53 /* AmpersandAmpersandToken */:
+                case 54 /* BarBarToken */:
+                case 69 /* BarEqualsToken */:
+                case 68 /* AmpersandEqualsToken */:
+                case 70 /* CaretEqualsToken */:
+                case 65 /* LessThanLessThanEqualsToken */:
+                case 66 /* GreaterThanGreaterThanEqualsToken */:
+                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                case 59 /* PlusEqualsToken */:
+                case 60 /* MinusEqualsToken */:
+                case 61 /* AsteriskEqualsToken */:
+                case 63 /* SlashEqualsToken */:
+                case 64 /* PercentEqualsToken */:
+                case 58 /* EqualsToken */:
+                case 26 /* CommaToken */:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+        function isPrefixUnaryExpressionOperatorToken(token) {
+            switch (token) {
+                case 37 /* PlusToken */:
+                case 38 /* MinusToken */:
+                case 52 /* TildeToken */:
+                case 51 /* ExclamationToken */:
+                case 43 /* PlusPlusToken */:
+                case 44 /* MinusMinusToken */:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+        function isKeyword(token) {
+            return token >= 72 /* FirstKeyword */ && token <= 142 /* LastKeyword */;
+        }
+        function classFromKind(token) {
+            if (isKeyword(token)) {
+                return 3 /* keyword */;
+            }
+            else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
+                return 5 /* operator */;
+            }
+            else if (token >= 17 /* FirstPunctuation */ && token <= 70 /* LastPunctuation */) {
+                return 10 /* punctuation */;
+            }
+            switch (token) {
+                case 8 /* NumericLiteral */:
+                    return 4 /* numericLiteral */;
+                case 9 /* StringLiteral */:
+                    return 6 /* stringLiteral */;
+                case 12 /* RegularExpressionLiteral */:
+                    return 7 /* regularExpressionLiteral */;
+                case 7 /* ConflictMarkerTrivia */:
+                case 3 /* MultiLineCommentTrivia */:
+                case 2 /* SingleLineCommentTrivia */:
+                    return 1 /* comment */;
+                case 5 /* WhitespaceTrivia */:
+                case 4 /* NewLineTrivia */:
+                    return 8 /* whiteSpace */;
+                case 71 /* Identifier */:
+                default:
+                    if (ts.isTemplateLiteralKind(token)) {
+                        return 6 /* stringLiteral */;
+                    }
+                    return 2 /* identifier */;
+            }
+        }
+        return {
+            getClassificationsForLine: getClassificationsForLine,
+            getEncodedLexicalClassifications: getEncodedLexicalClassifications
+        };
+    }
+    ts.createClassifier = createClassifier;
+    /* @internal */
+    function getSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
+        return convertClassifications(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
+    }
+    ts.getSemanticClassifications = getSemanticClassifications;
+    function checkForClassificationCancellation(cancellationToken, kind) {
+        // We don't want to actually call back into our host on every node to find out if we've
+        // been canceled.  That would be an enormous amount of chattyness, along with the all
+        // the overhead of marshalling the data to/from the host.  So instead we pick a few
+        // reasonable node kinds to bother checking on.  These node kinds represent high level
+        // constructs that we would expect to see commonly, but just at a far less frequent
+        // interval.
+        //
+        // For example, in checker.ts (around 750k) we only have around 600 of these constructs.
+        // That means we're calling back into the host around every 1.2k of the file we process.
+        // Lib.d.ts has similar numbers.
+        switch (kind) {
+            case 233 /* ModuleDeclaration */:
+            case 229 /* ClassDeclaration */:
+            case 230 /* InterfaceDeclaration */:
+            case 228 /* FunctionDeclaration */:
+                cancellationToken.throwIfCancellationRequested();
+        }
+    }
+    /* @internal */
+    function getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
+        var result = [];
+        processNode(sourceFile);
+        return { spans: result, endOfLineState: 0 /* None */ };
+        function pushClassification(start, length, type) {
+            result.push(start);
+            result.push(length);
+            result.push(type);
+        }
+        function classifySymbol(symbol, meaningAtPosition) {
+            var flags = symbol.getFlags();
+            if ((flags & 788448 /* Classifiable */) === 0 /* None */) {
+                return;
+            }
+            if (flags & 32 /* Class */) {
+                return 11 /* className */;
+            }
+            else if (flags & 384 /* Enum */) {
+                return 12 /* enumName */;
+            }
+            else if (flags & 524288 /* TypeAlias */) {
+                return 16 /* typeAliasName */;
+            }
+            else if (meaningAtPosition & 2 /* Type */) {
+                if (flags & 64 /* Interface */) {
+                    return 13 /* interfaceName */;
+                }
+                else if (flags & 262144 /* TypeParameter */) {
+                    return 15 /* typeParameterName */;
+                }
+            }
+            else if (flags & 1536 /* Module */) {
+                // Only classify a module as such if
+                //  - It appears in a namespace context.
+                //  - There exists a module declaration which actually impacts the value side.
+                if (meaningAtPosition & 4 /* Namespace */ ||
+                    (meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol))) {
+                    return 14 /* moduleName */;
+                }
+            }
+            return undefined;
+            /**
+             * Returns true if there exists a module that introduces entities on the value side.
+             */
+            function hasValueSideModule(symbol) {
+                return ts.forEach(symbol.declarations, function (declaration) {
+                    return declaration.kind === 233 /* ModuleDeclaration */ &&
+                        ts.getModuleInstanceState(declaration) === 1 /* Instantiated */;
+                });
+            }
+        }
+        function processNode(node) {
+            // Only walk into nodes that intersect the requested span.
+            if (node && ts.textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) {
+                var kind = node.kind;
+                checkForClassificationCancellation(cancellationToken, kind);
+                if (kind === 71 /* Identifier */ && !ts.nodeIsMissing(node)) {
+                    var identifier = node;
+                    // Only bother calling into the typechecker if this is an identifier that
+                    // could possibly resolve to a type name.  This makes classification run
+                    // in a third of the time it would normally take.
+                    if (classifiableNames.has(identifier.escapedText)) {
+                        var symbol = typeChecker.getSymbolAtLocation(node);
+                        if (symbol) {
+                            var type = classifySymbol(symbol, ts.getMeaningFromLocation(node));
+                            if (type) {
+                                pushClassification(node.getStart(), node.getWidth(), type);
+                            }
+                        }
+                    }
+                }
+                ts.forEachChild(node, processNode);
+            }
+        }
+    }
+    ts.getEncodedSemanticClassifications = getEncodedSemanticClassifications;
+    function getClassificationTypeName(type) {
+        switch (type) {
+            case 1 /* comment */: return "comment" /* comment */;
+            case 2 /* identifier */: return "identifier" /* identifier */;
+            case 3 /* keyword */: return "keyword" /* keyword */;
+            case 4 /* numericLiteral */: return "number" /* numericLiteral */;
+            case 5 /* operator */: return "operator" /* operator */;
+            case 6 /* stringLiteral */: return "string" /* stringLiteral */;
+            case 8 /* whiteSpace */: return "whitespace" /* whiteSpace */;
+            case 9 /* text */: return "text" /* text */;
+            case 10 /* punctuation */: return "punctuation" /* punctuation */;
+            case 11 /* className */: return "class name" /* className */;
+            case 12 /* enumName */: return "enum name" /* enumName */;
+            case 13 /* interfaceName */: return "interface name" /* interfaceName */;
+            case 14 /* moduleName */: return "module name" /* moduleName */;
+            case 15 /* typeParameterName */: return "type parameter name" /* typeParameterName */;
+            case 16 /* typeAliasName */: return "type alias name" /* typeAliasName */;
+            case 17 /* parameterName */: return "parameter name" /* parameterName */;
+            case 18 /* docCommentTagName */: return "doc comment tag name" /* docCommentTagName */;
+            case 19 /* jsxOpenTagName */: return "jsx open tag name" /* jsxOpenTagName */;
+            case 20 /* jsxCloseTagName */: return "jsx close tag name" /* jsxCloseTagName */;
+            case 21 /* jsxSelfClosingTagName */: return "jsx self closing tag name" /* jsxSelfClosingTagName */;
+            case 22 /* jsxAttribute */: return "jsx attribute" /* jsxAttribute */;
+            case 23 /* jsxText */: return "jsx text" /* jsxText */;
+            case 24 /* jsxAttributeStringLiteralValue */: return "jsx attribute string literal value" /* jsxAttributeStringLiteralValue */;
+        }
+    }
+    function convertClassifications(classifications) {
+        ts.Debug.assert(classifications.spans.length % 3 === 0);
+        var dense = classifications.spans;
+        var result = [];
+        for (var i = 0; i < dense.length; i += 3) {
+            result.push({
+                textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
+                classificationType: getClassificationTypeName(dense[i + 2])
+            });
+        }
+        return result;
+    }
+    /* @internal */
+    function getSyntacticClassifications(cancellationToken, sourceFile, span) {
+        return convertClassifications(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
+    }
+    ts.getSyntacticClassifications = getSyntacticClassifications;
+    /* @internal */
+    function getEncodedSyntacticClassifications(cancellationToken, sourceFile, span) {
+        var spanStart = span.start;
+        var spanLength = span.length;
+        // Make a scanner we can get trivia from.
+        var triviaScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
+        var mergeConflictScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
+        var result = [];
+        processElement(sourceFile);
+        return { spans: result, endOfLineState: 0 /* None */ };
+        function pushClassification(start, length, type) {
+            result.push(start);
+            result.push(length);
+            result.push(type);
+        }
+        function classifyLeadingTriviaAndGetTokenStart(token) {
+            triviaScanner.setTextPos(token.pos);
+            while (true) {
+                var start = triviaScanner.getTextPos();
+                // only bother scanning if we have something that could be trivia.
+                if (!ts.couldStartTrivia(sourceFile.text, start)) {
+                    return start;
+                }
+                var kind = triviaScanner.scan();
+                var end = triviaScanner.getTextPos();
+                var width = end - start;
+                // The moment we get something that isn't trivia, then stop processing.
+                if (!ts.isTrivia(kind)) {
+                    return start;
+                }
+                // Don't bother with newlines/whitespace.
+                if (kind === 4 /* NewLineTrivia */ || kind === 5 /* WhitespaceTrivia */) {
+                    continue;
+                }
+                // Only bother with the trivia if it at least intersects the span of interest.
+                if (ts.isComment(kind)) {
+                    classifyComment(token, kind, start, width);
+                    // Classifying a comment might cause us to reuse the trivia scanner
+                    // (because of jsdoc comments).  So after we classify the comment make
+                    // sure we set the scanner position back to where it needs to be.
+                    triviaScanner.setTextPos(end);
+                    continue;
+                }
+                if (kind === 7 /* ConflictMarkerTrivia */) {
+                    var text = sourceFile.text;
+                    var ch = text.charCodeAt(start);
+                    // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
+                    // in the classification stream.
+                    if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
+                        pushClassification(start, width, 1 /* comment */);
+                        continue;
+                    }
+                    // for the ||||||| and ======== markers, add a comment for the first line,
+                    // and then lex all subsequent lines up until the end of the conflict marker.
+                    ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
+                    classifyDisabledMergeCode(text, start, end);
+                }
+            }
+        }
+        function classifyComment(token, kind, start, width) {
+            if (kind === 3 /* MultiLineCommentTrivia */) {
+                // See if this is a doc comment.  If so, we'll classify certain portions of it
+                // specially.
+                var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width);
+                if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
+                    // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
+                    docCommentAndDiagnostics.jsDoc.parent = token;
+                    classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
+                    return;
+                }
+            }
+            // Simple comment.  Just add as is.
+            pushCommentRange(start, width);
+        }
+        function pushCommentRange(start, width) {
+            pushClassification(start, width, 1 /* comment */);
+        }
+        function classifyJSDocComment(docComment) {
+            var pos = docComment.pos;
+            if (docComment.tags) {
+                for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) {
+                    var tag = _a[_i];
+                    // As we walk through each tag, classify the portion of text from the end of
+                    // the last tag (or the start of the entire doc comment) as 'comment'.
+                    if (tag.pos !== pos) {
+                        pushCommentRange(pos, tag.pos - pos);
+                    }
+                    pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10 /* punctuation */); // "@"
+                    pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); // e.g. "param"
+                    pos = tag.tagName.end;
+                    switch (tag.kind) {
+                        case 279 /* JSDocParameterTag */:
+                            processJSDocParameterTag(tag);
+                            break;
+                        case 282 /* JSDocTemplateTag */:
+                            processJSDocTemplateTag(tag);
+                            break;
+                        case 281 /* JSDocTypeTag */:
+                            processElement(tag.typeExpression);
+                            break;
+                        case 280 /* JSDocReturnTag */:
+                            processElement(tag.typeExpression);
+                            break;
+                    }
+                    pos = tag.end;
+                }
+            }
+            if (pos !== docComment.end) {
+                pushCommentRange(pos, docComment.end - pos);
+            }
+            return;
+            function processJSDocParameterTag(tag) {
+                if (tag.isNameFirst) {
+                    pushCommentRange(pos, tag.name.pos - pos);
+                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
+                    pos = tag.name.end;
+                }
+                if (tag.typeExpression) {
+                    pushCommentRange(pos, tag.typeExpression.pos - pos);
+                    processElement(tag.typeExpression);
+                    pos = tag.typeExpression.end;
+                }
+                if (!tag.isNameFirst) {
+                    pushCommentRange(pos, tag.name.pos - pos);
+                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
+                    pos = tag.name.end;
+                }
+            }
+        }
+        function processJSDocTemplateTag(tag) {
+            for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) {
+                var child = _a[_i];
+                processElement(child);
+            }
+        }
+        function classifyDisabledMergeCode(text, start, end) {
+            // Classify the line that the ||||||| or ======= marker is on as a comment.
+            // Then just lex all further tokens and add them to the result.
+            var i;
+            for (i = start; i < end; i++) {
+                if (ts.isLineBreak(text.charCodeAt(i))) {
+                    break;
+                }
+            }
+            pushClassification(start, i - start, 1 /* comment */);
+            mergeConflictScanner.setTextPos(i);
+            while (mergeConflictScanner.getTextPos() < end) {
+                classifyDisabledCodeToken();
+            }
+        }
+        function classifyDisabledCodeToken() {
+            var start = mergeConflictScanner.getTextPos();
+            var tokenKind = mergeConflictScanner.scan();
+            var end = mergeConflictScanner.getTextPos();
+            var type = classifyTokenType(tokenKind);
+            if (type) {
+                pushClassification(start, end - start, type);
+            }
+        }
+        /**
+         * Returns true if node should be treated as classified and no further processing is required.
+         * False will mean that node is not classified and traverse routine should recurse into node contents.
+         */
+        function tryClassifyNode(node) {
+            if (ts.isJSDoc(node)) {
+                return true;
+            }
+            if (ts.nodeIsMissing(node)) {
+                return true;
+            }
+            var classifiedElementName = tryClassifyJsxElementName(node);
+            if (!ts.isToken(node) && node.kind !== 10 /* JsxText */ && classifiedElementName === undefined) {
+                return false;
+            }
+            var tokenStart = node.kind === 10 /* JsxText */ ? node.pos : classifyLeadingTriviaAndGetTokenStart(node);
+            var tokenWidth = node.end - tokenStart;
+            ts.Debug.assert(tokenWidth >= 0);
+            if (tokenWidth > 0) {
+                var type = classifiedElementName || classifyTokenType(node.kind, node);
+                if (type) {
+                    pushClassification(tokenStart, tokenWidth, type);
+                }
+            }
+            return true;
+        }
+        function tryClassifyJsxElementName(token) {
+            switch (token.parent && token.parent.kind) {
+                case 251 /* JsxOpeningElement */:
+                    if (token.parent.tagName === token) {
+                        return 19 /* jsxOpenTagName */;
+                    }
+                    break;
+                case 252 /* JsxClosingElement */:
+                    if (token.parent.tagName === token) {
+                        return 20 /* jsxCloseTagName */;
+                    }
+                    break;
+                case 250 /* JsxSelfClosingElement */:
+                    if (token.parent.tagName === token) {
+                        return 21 /* jsxSelfClosingTagName */;
+                    }
+                    break;
+                case 253 /* JsxAttribute */:
+                    if (token.parent.name === token) {
+                        return 22 /* jsxAttribute */;
+                    }
+                    break;
+            }
+            return undefined;
+        }
+        // for accurate classification, the actual token should be passed in.  however, for
+        // cases like 'disabled merge code' classification, we just get the token kind and
+        // classify based on that instead.
+        function classifyTokenType(tokenKind, token) {
+            if (ts.isKeyword(tokenKind)) {
+                return 3 /* keyword */;
+            }
+            // Special case < and >  If they appear in a generic context they are punctuation,
+            // not operators.
+            if (tokenKind === 27 /* LessThanToken */ || tokenKind === 29 /* GreaterThanToken */) {
+                // If the node owning the token has a type argument list or type parameter list, then
+                // we can effectively assume that a '<' and '>' belong to those lists.
+                if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) {
+                    return 10 /* punctuation */;
+                }
+            }
+            if (ts.isPunctuation(tokenKind)) {
+                if (token) {
+                    if (tokenKind === 58 /* EqualsToken */) {
+                        // the '=' in a variable declaration is special cased here.
+                        if (token.parent.kind === 226 /* VariableDeclaration */ ||
+                            token.parent.kind === 149 /* PropertyDeclaration */ ||
+                            token.parent.kind === 146 /* Parameter */ ||
+                            token.parent.kind === 253 /* JsxAttribute */) {
+                            return 5 /* operator */;
+                        }
+                    }
+                    if (token.parent.kind === 194 /* BinaryExpression */ ||
+                        token.parent.kind === 192 /* PrefixUnaryExpression */ ||
+                        token.parent.kind === 193 /* PostfixUnaryExpression */ ||
+                        token.parent.kind === 195 /* ConditionalExpression */) {
+                        return 5 /* operator */;
+                    }
+                }
+                return 10 /* punctuation */;
+            }
+            else if (tokenKind === 8 /* NumericLiteral */) {
+                return 4 /* numericLiteral */;
+            }
+            else if (tokenKind === 9 /* StringLiteral */) {
+                return token.parent.kind === 253 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */;
+            }
+            else if (tokenKind === 12 /* RegularExpressionLiteral */) {
+                // TODO: we should get another classification type for these literals.
+                return 6 /* stringLiteral */;
+            }
+            else if (ts.isTemplateLiteralKind(tokenKind)) {
+                // TODO (drosen): we should *also* get another classification type for these literals.
+                return 6 /* stringLiteral */;
+            }
+            else if (tokenKind === 10 /* JsxText */) {
+                return 23 /* jsxText */;
+            }
+            else if (tokenKind === 71 /* Identifier */) {
+                if (token) {
+                    switch (token.parent.kind) {
+                        case 229 /* ClassDeclaration */:
+                            if (token.parent.name === token) {
+                                return 11 /* className */;
+                            }
+                            return;
+                        case 145 /* TypeParameter */:
+                            if (token.parent.name === token) {
+                                return 15 /* typeParameterName */;
+                            }
+                            return;
+                        case 230 /* InterfaceDeclaration */:
+                            if (token.parent.name === token) {
+                                return 13 /* interfaceName */;
+                            }
+                            return;
+                        case 232 /* EnumDeclaration */:
+                            if (token.parent.name === token) {
+                                return 12 /* enumName */;
+                            }
+                            return;
+                        case 233 /* ModuleDeclaration */:
+                            if (token.parent.name === token) {
+                                return 14 /* moduleName */;
+                            }
+                            return;
+                        case 146 /* Parameter */:
+                            if (token.parent.name === token) {
+                                return ts.isThisIdentifier(token) ? 3 /* keyword */ : 17 /* parameterName */;
+                            }
+                            return;
+                    }
+                }
+                return 2 /* identifier */;
+            }
+        }
+        function processElement(element) {
+            if (!element) {
+                return;
+            }
+            // Ignore nodes that don't intersect the original span to classify.
+            if (ts.decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
+                checkForClassificationCancellation(cancellationToken, element.kind);
+                for (var _i = 0, _a = element.getChildren(sourceFile); _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    if (!tryClassifyNode(child)) {
+                        // Recurse into our child nodes.
+                        processElement(child);
+                    }
+                }
+            }
+        }
+    }
+    ts.getEncodedSyntacticClassifications = getEncodedSyntacticClassifications;
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var Completions;
+    (function (Completions) {
+        var PathCompletions;
+        (function (PathCompletions) {
+            function getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker) {
+                var literalValue = ts.normalizeSlashes(node.text);
+                var scriptPath = node.getSourceFile().path;
+                var scriptDirectory = ts.getDirectoryPath(scriptPath);
+                var span = getDirectoryFragmentTextSpan(node.text, node.getStart() + 1);
+                var entries;
+                if (isPathRelativeToScript(literalValue) || ts.isRootedDiskPath(literalValue)) {
+                    var extensions = ts.getSupportedExtensions(compilerOptions);
+                    if (compilerOptions.rootDirs) {
+                        entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath);
+                    }
+                    else {
+                        entries = getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath);
+                    }
+                }
+                else {
+                    // Check for node modules
+                    entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
+                }
+                return {
+                    isGlobalCompletion: false,
+                    isMemberCompletion: false,
+                    isNewIdentifierLocation: true,
+                    entries: entries
+                };
+            }
+            PathCompletions.getStringLiteralCompletionEntriesFromModuleNames = getStringLiteralCompletionEntriesFromModuleNames;
+            /**
+             * Takes a script path and returns paths for all potential folders that could be merged with its
+             * containing folder via the "rootDirs" compiler option
+             */
+            function getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase) {
+                // Make all paths absolute/normalized if they are not already
+                rootDirs = ts.map(rootDirs, function (rootDirectory) { return ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory)); });
+                // Determine the path to the directory containing the script relative to the root directory it is contained within
+                var relativeDirectory = ts.forEach(rootDirs, function (rootDirectory) {
+                    return ts.containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined;
+                });
+                // Now find a path for each potential directory that is to be merged with the one containing the script
+                return ts.deduplicate(ts.map(rootDirs, function (rootDirectory) { return ts.combinePaths(rootDirectory, relativeDirectory); }));
+            }
+            function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs, fragment, scriptPath, extensions, includeExtensions, span, compilerOptions, host, exclude) {
+                var basePath = compilerOptions.project || host.getCurrentDirectory();
+                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
+                var baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
+                var result = [];
+                for (var _i = 0, baseDirectories_1 = baseDirectories; _i < baseDirectories_1.length; _i++) {
+                    var baseDirectory = baseDirectories_1[_i];
+                    getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result);
+                }
+                return result;
+            }
+            /**
+             * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
+             */
+            function getCompletionEntriesForDirectoryFragment(fragment, scriptPath, extensions, includeExtensions, span, host, exclude, result) {
+                if (result === void 0) { result = []; }
+                if (fragment === undefined) {
+                    fragment = "";
+                }
+                fragment = ts.normalizeSlashes(fragment);
+                /**
+                 * Remove the basename from the path. Note that we don't use the basename to filter completions;
+                 * the client is responsible for refining completions.
+                 */
+                fragment = ts.getDirectoryPath(fragment);
+                if (fragment === "") {
+                    fragment = "." + ts.directorySeparator;
+                }
+                fragment = ts.ensureTrailingDirectorySeparator(fragment);
+                var absolutePath = normalizeAndPreserveTrailingSlash(ts.isRootedDiskPath(fragment) ? fragment : ts.combinePaths(scriptPath, fragment));
+                var baseDirectory = ts.getDirectoryPath(absolutePath);
+                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
+                if (tryDirectoryExists(host, baseDirectory)) {
+                    // Enumerate the available files if possible
+                    var files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
+                    if (files) {
+                        /**
+                         * Multiple file entries might map to the same truncated name once we remove extensions
+                         * (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
+                         *
+                         * both foo.ts and foo.tsx become foo
+                         */
+                        var foundFiles = ts.createMap();
+                        for (var _i = 0, files_3 = files; _i < files_3.length; _i++) {
+                            var filePath = files_3[_i];
+                            filePath = ts.normalizePath(filePath);
+                            if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === 0 /* EqualTo */) {
+                                continue;
+                            }
+                            var foundFileName = includeExtensions ? ts.getBaseFileName(filePath) : ts.removeFileExtension(ts.getBaseFileName(filePath));
+                            if (!foundFiles.get(foundFileName)) {
+                                foundFiles.set(foundFileName, true);
+                            }
+                        }
+                        ts.forEachKey(foundFiles, function (foundFile) {
+                            result.push(createCompletionEntryForModule(foundFile, "script" /* scriptElement */, span));
+                        });
+                    }
+                    // If possible, get folder completion as well
+                    var directories = tryGetDirectories(host, baseDirectory);
+                    if (directories) {
+                        for (var _a = 0, directories_2 = directories; _a < directories_2.length; _a++) {
+                            var directory = directories_2[_a];
+                            var directoryName = ts.getBaseFileName(ts.normalizePath(directory));
+                            result.push(createCompletionEntryForModule(directoryName, "directory" /* directory */, span));
+                        }
+                    }
+                }
+                return result;
+            }
+            /**
+             * Check all of the declared modules and those in node modules. Possible sources of modules:
+             *      Modules that are found by the type checker
+             *      Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
+             *      Modules from node_modules (i.e. those listed in package.json)
+             *          This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
+             */
+            function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, span, compilerOptions, host, typeChecker) {
+                var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
+                var result;
+                if (baseUrl) {
+                    var fileExtensions = ts.getSupportedExtensions(compilerOptions);
+                    var projectDir = compilerOptions.project || host.getCurrentDirectory();
+                    var absolute = ts.isRootedDiskPath(baseUrl) ? baseUrl : ts.combinePaths(projectDir, baseUrl);
+                    result = getCompletionEntriesForDirectoryFragment(fragment, ts.normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host);
+                    if (paths) {
+                        for (var path in paths) {
+                            if (paths.hasOwnProperty(path)) {
+                                if (path === "*") {
+                                    if (paths[path]) {
+                                        for (var _i = 0, _a = paths[path]; _i < _a.length; _i++) {
+                                            var pattern = _a[_i];
+                                            for (var _b = 0, _c = getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host); _b < _c.length; _b++) {
+                                                var match = _c[_b];
+                                                result.push(createCompletionEntryForModule(match, "external module name" /* externalModuleName */, span));
+                                            }
+                                        }
+                                    }
+                                }
+                                else if (ts.startsWith(path, fragment)) {
+                                    var entry = paths[path] && paths[path].length === 1 && paths[path][0];
+                                    if (entry) {
+                                        result.push(createCompletionEntryForModule(path, "external module name" /* externalModuleName */, span));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                else {
+                    result = [];
+                }
+                getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
+                for (var _d = 0, _e = enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host); _d < _e.length; _d++) {
+                    var moduleName = _e[_d];
+                    result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span));
+                }
+                return result;
+            }
+            function getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host) {
+                if (host.readDirectory) {
+                    var parsed = ts.hasZeroOrOneAsteriskCharacter(pattern) ? ts.tryParsePattern(pattern) : undefined;
+                    if (parsed) {
+                        // The prefix has two effective parts: the directory path and the base component after the filepath that is not a
+                        // full directory component. For example: directory/path/of/prefix/base*
+                        var normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix);
+                        var normalizedPrefixDirectory = ts.getDirectoryPath(normalizedPrefix);
+                        var normalizedPrefixBase = ts.getBaseFileName(normalizedPrefix);
+                        var fragmentHasPath = ts.stringContains(fragment, ts.directorySeparator);
+                        // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
+                        var expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + ts.getDirectoryPath(fragment)) : normalizedPrefixDirectory;
+                        var normalizedSuffix = ts.normalizePath(parsed.suffix);
+                        var baseDirectory = ts.combinePaths(baseUrl, expandedPrefixDirectory);
+                        var completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
+                        // If we have a suffix, then we need to read the directory all the way down. We could create a glob
+                        // that encodes the suffix, but we would have to escape the character "?" which readDirectory
+                        // doesn't support. For now, this is safer but slower
+                        var includeGlob = normalizedSuffix ? "**/*" : "./*";
+                        var matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]);
+                        if (matches) {
+                            var result = [];
+                            // Trim away prefix and suffix
+                            for (var _i = 0, matches_1 = matches; _i < matches_1.length; _i++) {
+                                var match = matches_1[_i];
+                                var normalizedMatch = ts.normalizePath(match);
+                                if (!ts.endsWith(normalizedMatch, normalizedSuffix) || !ts.startsWith(normalizedMatch, completePrefix)) {
+                                    continue;
+                                }
+                                var start = completePrefix.length;
+                                var length_7 = normalizedMatch.length - start - normalizedSuffix.length;
+                                result.push(ts.removeFileExtension(normalizedMatch.substr(start, length_7)));
+                            }
+                            return result;
+                        }
+                    }
+                }
+                return undefined;
+            }
+            function enumeratePotentialNonRelativeModules(fragment, scriptPath, options, typeChecker, host) {
+                // Check If this is a nested module
+                var isNestedModule = ts.stringContains(fragment, ts.directorySeparator);
+                var moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(ts.directorySeparator)) : undefined;
+                // Get modules that the type checker picked up
+                var ambientModules = ts.map(typeChecker.getAmbientModules(), function (sym) { return ts.stripQuotes(sym.name); });
+                var nonRelativeModuleNames = ts.filter(ambientModules, function (moduleName) { return ts.startsWith(moduleName, fragment); });
+                // Nested modules of the form "module-name/sub" need to be adjusted to only return the string
+                // after the last '/' that appears in the fragment because that's where the replacement span
+                // starts
+                if (isNestedModule) {
+                    var moduleNameWithSeperator_1 = ts.ensureTrailingDirectorySeparator(moduleNameFragment);
+                    nonRelativeModuleNames = ts.map(nonRelativeModuleNames, function (nonRelativeModuleName) {
+                        return ts.removePrefix(nonRelativeModuleName, moduleNameWithSeperator_1);
+                    });
+                }
+                if (!options.moduleResolution || options.moduleResolution === ts.ModuleResolutionKind.NodeJs) {
+                    for (var _i = 0, _a = enumerateNodeModulesVisibleToScript(host, scriptPath); _i < _a.length; _i++) {
+                        var visibleModule = _a[_i];
+                        if (!isNestedModule) {
+                            nonRelativeModuleNames.push(visibleModule.moduleName);
+                        }
+                        else if (ts.startsWith(visibleModule.moduleName, moduleNameFragment)) {
+                            var nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, ts.supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]);
+                            if (nestedFiles) {
+                                for (var _b = 0, nestedFiles_1 = nestedFiles; _b < nestedFiles_1.length; _b++) {
+                                    var f = nestedFiles_1[_b];
+                                    f = ts.normalizePath(f);
+                                    var nestedModule = ts.removeFileExtension(ts.getBaseFileName(f));
+                                    nonRelativeModuleNames.push(nestedModule);
+                                }
+                            }
+                        }
+                    }
+                }
+                return ts.deduplicate(nonRelativeModuleNames);
+            }
+            function getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host) {
+                var token = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+                if (!token) {
+                    return undefined;
+                }
+                var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
+                if (!commentRanges || !commentRanges.length) {
+                    return undefined;
+                }
+                var range = ts.forEach(commentRanges, function (commentRange) { return position >= commentRange.pos && position <= commentRange.end && commentRange; });
+                if (!range) {
+                    return undefined;
+                }
+                var completionInfo = {
+                    /**
+                     * We don't want the editor to offer any other completions, such as snippets, inside a comment.
+                     */
+                    isGlobalCompletion: false,
+                    isMemberCompletion: false,
+                    /**
+                     * The user may type in a path that doesn't yet exist, creating a "new identifier"
+                     * with respect to the collection of identifiers the server is aware of.
+                     */
+                    isNewIdentifierLocation: true,
+                    entries: []
+                };
+                var text = sourceFile.text.substr(range.pos, position - range.pos);
+                var match = tripleSlashDirectiveFragmentRegex.exec(text);
+                if (match) {
+                    var prefix = match[1];
+                    var kind = match[2];
+                    var toComplete = match[3];
+                    var scriptPath = ts.getDirectoryPath(sourceFile.path);
+                    if (kind === "path") {
+                        // Give completions for a relative path
+                        var span_10 = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
+                        completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, ts.getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span_10, host, sourceFile.path);
+                    }
+                    else {
+                        // Give completions based on the typings available
+                        var span_11 = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
+                        completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span_11);
+                    }
+                }
+                return completionInfo;
+            }
+            PathCompletions.getTripleSlashReferenceCompletion = getTripleSlashReferenceCompletion;
+            function getCompletionEntriesFromTypings(host, options, scriptPath, span, result) {
+                if (result === void 0) { result = []; }
+                // Check for typings specified in compiler options
+                if (options.types) {
+                    for (var _i = 0, _a = options.types; _i < _a.length; _i++) {
+                        var moduleName = _a[_i];
+                        result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span));
+                    }
+                }
+                else if (host.getDirectories) {
+                    var typeRoots = void 0;
+                    try {
+                        // Wrap in try catch because getEffectiveTypeRoots touches the filesystem
+                        typeRoots = ts.getEffectiveTypeRoots(options, host);
+                    }
+                    catch (e) { }
+                    if (typeRoots) {
+                        for (var _b = 0, typeRoots_2 = typeRoots; _b < typeRoots_2.length; _b++) {
+                            var root = typeRoots_2[_b];
+                            getCompletionEntriesFromDirectories(host, root, span, result);
+                        }
+                    }
+                }
+                if (host.getDirectories) {
+                    // Also get all @types typings installed in visible node_modules directories
+                    for (var _c = 0, _d = findPackageJsons(scriptPath, host); _c < _d.length; _c++) {
+                        var packageJson = _d[_c];
+                        var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
+                        getCompletionEntriesFromDirectories(host, typesDir, span, result);
+                    }
+                }
+                return result;
+            }
+            function getCompletionEntriesFromDirectories(host, directory, span, result) {
+                if (host.getDirectories && tryDirectoryExists(host, directory)) {
+                    var directories = tryGetDirectories(host, directory);
+                    if (directories) {
+                        for (var _i = 0, directories_3 = directories; _i < directories_3.length; _i++) {
+                            var typeDirectory = directories_3[_i];
+                            typeDirectory = ts.normalizePath(typeDirectory);
+                            result.push(createCompletionEntryForModule(ts.getBaseFileName(typeDirectory), "external module name" /* externalModuleName */, span));
+                        }
+                    }
+                }
+            }
+            function findPackageJsons(currentDir, host) {
+                var paths = [];
+                var currentConfigPath;
+                while (true) {
+                    currentConfigPath = ts.findConfigFile(currentDir, function (f) { return tryFileExists(host, f); }, "package.json");
+                    if (currentConfigPath) {
+                        paths.push(currentConfigPath);
+                        currentDir = ts.getDirectoryPath(currentConfigPath);
+                        var parent = ts.getDirectoryPath(currentDir);
+                        if (currentDir === parent) {
+                            break;
+                        }
+                        currentDir = parent;
+                    }
+                    else {
+                        break;
+                    }
+                }
+                return paths;
+            }
+            function enumerateNodeModulesVisibleToScript(host, scriptPath) {
+                var result = [];
+                if (host.readFile && host.fileExists) {
+                    for (var _i = 0, _a = findPackageJsons(scriptPath, host); _i < _a.length; _i++) {
+                        var packageJson = _a[_i];
+                        var contents = tryReadingPackageJson(packageJson);
+                        if (!contents) {
+                            return;
+                        }
+                        var nodeModulesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules");
+                        var foundModuleNames = [];
+                        // Provide completions for all non @types dependencies
+                        for (var _b = 0, nodeModulesDependencyKeys_1 = nodeModulesDependencyKeys; _b < nodeModulesDependencyKeys_1.length; _b++) {
+                            var key = nodeModulesDependencyKeys_1[_b];
+                            addPotentialPackageNames(contents[key], foundModuleNames);
+                        }
+                        for (var _c = 0, foundModuleNames_1 = foundModuleNames; _c < foundModuleNames_1.length; _c++) {
+                            var moduleName = foundModuleNames_1[_c];
+                            var moduleDir = ts.combinePaths(nodeModulesDir, moduleName);
+                            result.push({
+                                moduleName: moduleName,
+                                moduleDir: moduleDir
+                            });
+                        }
+                    }
+                }
+                return result;
+                function tryReadingPackageJson(filePath) {
+                    try {
+                        var fileText = tryReadFile(host, filePath);
+                        return fileText ? JSON.parse(fileText) : undefined;
+                    }
+                    catch (e) {
+                        return undefined;
+                    }
+                }
+                function addPotentialPackageNames(dependencies, result) {
+                    if (dependencies) {
+                        for (var dep in dependencies) {
+                            if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) {
+                                result.push(dep);
+                            }
+                        }
+                    }
+                }
+            }
+            function createCompletionEntryForModule(name, kind, replacementSpan) {
+                return { name: name, kind: kind, kindModifiers: "" /* none */, sortText: name, replacementSpan: replacementSpan };
+            }
+            // Replace everything after the last directory seperator that appears
+            function getDirectoryFragmentTextSpan(text, textStart) {
+                var index = text.lastIndexOf(ts.directorySeparator);
+                var offset = index !== -1 ? index + 1 : 0;
+                return { start: textStart + offset, length: text.length - offset };
+            }
+            // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
+            function isPathRelativeToScript(path) {
+                if (path && path.length >= 2 && path.charCodeAt(0) === 46 /* dot */) {
+                    var slashIndex = path.length >= 3 && path.charCodeAt(1) === 46 /* dot */ ? 2 : 1;
+                    var slashCharCode = path.charCodeAt(slashIndex);
+                    return slashCharCode === 47 /* slash */ || slashCharCode === 92 /* backslash */;
+                }
+                return false;
+            }
+            function normalizeAndPreserveTrailingSlash(path) {
+                return ts.hasTrailingDirectorySeparator(path) ? ts.ensureTrailingDirectorySeparator(ts.normalizePath(path)) : ts.normalizePath(path);
+            }
+            /**
+             * Matches a triple slash reference directive with an incomplete string literal for its path. Used
+             * to determine if the caret is currently within the string literal and capture the literal fragment
+             * for completions.
+             * For example, this matches
+             *
+             * /// <reference path="fragment
+             *
+             * but not
+             *
+             * /// <reference path="fragment"
+             */
+            var tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
+            var nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
+            function tryGetDirectories(host, directoryName) {
+                return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
+            }
+            function tryReadDirectory(host, path, extensions, exclude, include) {
+                return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
+            }
+            function tryReadFile(host, path) {
+                return tryIOAndConsumeErrors(host, host.readFile, path);
+            }
+            function tryFileExists(host, path) {
+                return tryIOAndConsumeErrors(host, host.fileExists, path);
+            }
+            function tryDirectoryExists(host, path) {
+                try {
+                    return ts.directoryProbablyExists(path, host);
+                }
+                catch (e) { }
+                return undefined;
+            }
+            function tryIOAndConsumeErrors(host, toApply) {
+                var args = [];
+                for (var _i = 2; _i < arguments.length; _i++) {
+                    args[_i - 2] = arguments[_i];
+                }
+                try {
+                    return toApply && toApply.apply(host, args);
+                }
+                catch (e) { }
+                return undefined;
+            }
+        })(PathCompletions = Completions.PathCompletions || (Completions.PathCompletions = {}));
+    })(Completions = ts.Completions || (ts.Completions = {}));
+})(ts || (ts = {}));
+/// <reference path="./pathCompletions.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    var Completions;
+    (function (Completions) {
+        var KeywordCompletionFilters;
+        (function (KeywordCompletionFilters) {
+            KeywordCompletionFilters[KeywordCompletionFilters["None"] = 0] = "None";
+            KeywordCompletionFilters[KeywordCompletionFilters["ClassElementKeywords"] = 1] = "ClassElementKeywords";
+            KeywordCompletionFilters[KeywordCompletionFilters["ConstructorParameterKeywords"] = 2] = "ConstructorParameterKeywords";
+        })(KeywordCompletionFilters || (KeywordCompletionFilters = {}));
+        function getCompletionsAtPosition(host, typeChecker, log, compilerOptions, sourceFile, position, allSourceFiles) {
+            if (ts.isInReferenceComment(sourceFile, position)) {
+                return Completions.PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
+            }
+            if (ts.isInString(sourceFile, position)) {
+                return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
+            }
+            var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
+            if (!completionData) {
+                return undefined;
+            }
+            var symbols = completionData.symbols, isGlobalCompletion = completionData.isGlobalCompletion, isMemberCompletion = completionData.isMemberCompletion, allowStringLiteral = completionData.allowStringLiteral, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, request = completionData.request, keywordFilters = completionData.keywordFilters, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap;
+            if (sourceFile.languageVariant === 1 /* JSX */ &&
+                location && location.parent && location.parent.kind === 252 /* JsxClosingElement */) {
+                // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
+                // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
+                // For example:
+                //     var x = <div> </ /*1*/>  completion list at "1" will contain "div" with type any
+                var tagName = location.parent.parent.openingElement.tagName;
+                return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false,
+                    entries: [{
+                            name: tagName.getFullText(),
+                            kind: "class" /* classElement */,
+                            kindModifiers: undefined,
+                            sortText: "0",
+                        }] };
+            }
+            if (request) {
+                var entries_2 = request.kind === "JsDocTagName"
+                    // If the current position is a jsDoc tag name, only tag names should be provided for completion
+                    ? ts.JsDoc.getJSDocTagNameCompletions()
+                    : request.kind === "JsDocTag"
+                        // If the current position is a jsDoc tag, only tags should be provided for completion
+                        ? ts.JsDoc.getJSDocTagCompletions()
+                        : ts.JsDoc.getJSDocParameterNameCompletions(request.tag);
+                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_2 };
+            }
+            var entries = [];
+            if (ts.isSourceFileJavaScript(sourceFile)) {
+                var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
+                getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries);
+            }
+            else {
+                if ((!symbols || symbols.length === 0) && keywordFilters === 0 /* None */) {
+                    return undefined;
+                }
+                getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
+            }
+            // TODO add filter for keyword based on type/value/namespace and also location
+            // Add all keywords if
+            // - this is not a member completion list (all the keywords)
+            // - other filters are enabled in required scenario so add those keywords
+            if (keywordFilters !== 0 /* None */ || !isMemberCompletion) {
+                ts.addRange(entries, getKeywordCompletions(keywordFilters));
+            }
+            return { isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
+        }
+        Completions.getCompletionsAtPosition = getCompletionsAtPosition;
+        function getJavaScriptCompletionEntries(sourceFile, position, uniqueNames, target, entries) {
+            ts.getNameTable(sourceFile).forEach(function (pos, name) {
+                // Skip identifiers produced only from the current location
+                if (pos === position) {
+                    return;
+                }
+                var realName = ts.unescapeLeadingUnderscores(name);
+                if (uniqueNames.has(realName)) {
+                    return;
+                }
+                uniqueNames.set(realName, true);
+                var displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false);
+                if (displayName) {
+                    entries.push({
+                        name: displayName,
+                        kind: "warning" /* warning */,
+                        kindModifiers: "",
+                        sortText: "1"
+                    });
+                }
+            });
+        }
+        function createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin) {
+            // Try to get a valid display name for this symbol, if we could not find one, then ignore it.
+            // We would like to only show things that can be added after a dot, so for instance numeric properties can
+            // not be accessed with a dot (a.1 <- invalid)
+            var displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral);
+            if (!displayName) {
+                return undefined;
+            }
+            // TODO(drosen): Right now we just permit *all* semantic meanings when calling
+            // 'getSymbolKind' which is permissible given that it is backwards compatible; but
+            // really we should consider passing the meaning for the node so that we don't report
+            // that a suggestion for a value is an interface.  We COULD also just do what
+            // 'getSymbolModifiers' does, which is to use the first declaration.
+            // Use a 'sortText' of 0' so that all symbol completion entries come before any other
+            // entries (like JavaScript identifier entries).
+            return {
+                name: displayName,
+                kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
+                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
+                sortText: "0",
+                source: getSourceFromOrigin(origin),
+                hasAction: origin === undefined ? undefined : true,
+            };
+        }
+        function getSourceFromOrigin(origin) {
+            return origin && ts.stripQuotes(origin.moduleSymbol.name);
+        }
+        function getCompletionEntriesFromSymbols(symbols, entries, location, performCharacterChecks, typeChecker, target, log, allowStringLiteral, symbolToOriginInfoMap) {
+            var start = ts.timestamp();
+            // Tracks unique names.
+            // We don't set this for global variables or completions from external module exports, because we can have multiple of those.
+            // Based on the order we add things we will always see locals first, then globals, then module exports.
+            // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
+            var uniques = ts.createMap();
+            if (symbols) {
+                for (var _i = 0, symbols_5 = symbols; _i < symbols_5.length; _i++) {
+                    var symbol = symbols_5[_i];
+                    var origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[ts.getSymbolId(symbol)] : undefined;
+                    var entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin);
+                    if (!entry) {
+                        continue;
+                    }
+                    var name = entry.name;
+                    if (uniques.has(name)) {
+                        continue;
+                    }
+                    // Latter case tests whether this is a global variable.
+                    if (!origin && !(symbol.parent === undefined && !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === location.getSourceFile(); }))) {
+                        uniques.set(name, true);
+                    }
+                    entries.push(entry);
+                }
+            }
+            log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start));
+            return uniques;
+        }
+        function getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log) {
+            var node = ts.findPrecedingToken(position, sourceFile);
+            if (!node || node.kind !== 9 /* StringLiteral */) {
+                return undefined;
+            }
+            if (node.parent.kind === 261 /* PropertyAssignment */ &&
+                node.parent.parent.kind === 178 /* ObjectLiteralExpression */ &&
+                node.parent.name === node) {
+                // Get quoted name of properties of the object literal expression
+                // i.e. interface ConfigFiles {
+                //          'jspm:dev': string
+                //      }
+                //      let files: ConfigFiles = {
+                //          '/*completion position*/'
+                //      }
+                //
+                //      function foo(c: ConfigFiles) {}
+                //      foo({
+                //          '/*completion position*/'
+                //      });
+                return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log);
+            }
+            else if (ts.isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) {
+                // Get all names of properties on the expression
+                // i.e. interface A {
+                //      'prop1': string
+                // }
+                // let a: A;
+                // a['/*completion position*/']
+                return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
+            }
+            else if (node.parent.kind === 238 /* ImportDeclaration */ || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node) || ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
+                // Get all known external module names or complete a path to a module
+                // i.e. import * as ns from "/*completion position*/";
+                //      import x = require("/*completion position*/");
+                //      var y = require("/*completion position*/");
+                return Completions.PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker);
+            }
+            else if (isEqualityExpression(node.parent)) {
+                // Get completions from the type of the other operand
+                // i.e. switch (a) {
+                //         case '/*completion position*/'
+                //      }
+                return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
+            }
+            else if (ts.isCaseOrDefaultClause(node.parent)) {
+                // Get completions from the type of the switch expression
+                // i.e. x === '/*completion position'
+                return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.parent.parent.expression), typeChecker);
+            }
+            else {
+                var argumentInfo = ts.SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
+                if (argumentInfo) {
+                    // Get string literal completions from specialized signatures of the target
+                    // i.e. declare function f(a: 'A');
+                    // f("/*completion position*/")
+                    return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker);
+                }
+                // Get completion for string literal from string literal type
+                // i.e. var x: "hi" | "hello" = "/*completion position*/"
+                return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker);
+            }
+        }
+        function getStringLiteralCompletionEntriesFromPropertyAssignment(element, typeChecker, target, log) {
+            var type = typeChecker.getContextualType(element.parent);
+            var entries = [];
+            if (type) {
+                getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
+                if (entries.length) {
+                    return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries };
+                }
+            }
+        }
+        function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) {
+            var candidates = [];
+            var entries = [];
+            var uniques = ts.createMap();
+            typeChecker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
+            for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
+                var candidate = candidates_1[_i];
+                addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker, uniques);
+            }
+            if (entries.length) {
+                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries: entries };
+            }
+            return undefined;
+        }
+        function getStringLiteralCompletionEntriesFromElementAccess(node, typeChecker, target, log) {
+            var type = typeChecker.getTypeAtLocation(node.expression);
+            var entries = [];
+            if (type) {
+                getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
+                if (entries.length) {
+                    return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries };
+                }
+            }
+            return undefined;
+        }
+        function getStringLiteralCompletionEntriesFromType(type, typeChecker) {
+            if (type) {
+                var entries = [];
+                addStringLiteralCompletionsFromType(type, entries, typeChecker);
+                if (entries.length) {
+                    return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
+                }
+            }
+            return undefined;
+        }
+        function addStringLiteralCompletionsFromType(type, result, typeChecker, uniques) {
+            if (uniques === void 0) { uniques = ts.createMap(); }
+            if (type && type.flags & 16384 /* TypeParameter */) {
+                type = typeChecker.getBaseConstraintOfType(type);
+            }
+            if (!type) {
+                return;
+            }
+            if (type.flags & 65536 /* Union */) {
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var t = _a[_i];
+                    addStringLiteralCompletionsFromType(t, result, typeChecker, uniques);
+                }
+            }
+            else if (type.flags & 32 /* StringLiteral */ && !(type.flags & 256 /* EnumLiteral */)) {
+                var name = type.value;
+                if (!uniques.has(name)) {
+                    uniques.set(name, true);
+                    result.push({
+                        name: name,
+                        kindModifiers: "" /* none */,
+                        kind: "var" /* variableElement */,
+                        sortText: "0"
+                    });
+                }
+            }
+        }
+        function getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, _a, allSourceFiles) {
+            var name = _a.name, source = _a.source;
+            var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
+            if (!completionData) {
+                return undefined;
+            }
+            var symbols = completionData.symbols, location = completionData.location, allowStringLiteral = completionData.allowStringLiteral, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap;
+            // Find the symbol with the matching entry name.
+            // We don't need to perform character checks here because we're only comparing the
+            // name against 'entryName' (which is known to be good), not building a new
+            // completion entry.
+            var symbol = ts.find(symbols, function (s) {
+                return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name
+                    && getSourceFromOrigin(symbolToOriginInfoMap[ts.getSymbolId(s)]) === source;
+            });
+            return symbol && { symbol: symbol, location: location, symbolToOriginInfoMap: symbolToOriginInfoMap };
+        }
+        function getCompletionEntryDetails(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles, host, rulesProvider) {
+            var name = entryId.name, source = entryId.source;
+            // Compute all the completion symbols again.
+            var symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
+            if (symbolCompletion) {
+                var symbol = symbolCompletion.symbol, location = symbolCompletion.location, symbolToOriginInfoMap = symbolCompletion.symbolToOriginInfoMap;
+                var codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider);
+                var kindModifiers = ts.SymbolDisplay.getSymbolModifiers(symbol);
+                var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, 7 /* All */), displayParts = _a.displayParts, documentation = _a.documentation, symbolKind = _a.symbolKind, tags = _a.tags;
+                return { name: name, kindModifiers: kindModifiers, kind: symbolKind, displayParts: displayParts, documentation: documentation, tags: tags, codeActions: codeActions, source: source === undefined ? undefined : [ts.textPart(source)] };
+            }
+            // Didn't find a symbol with this name.  See if we can find a keyword instead.
+            if (source === undefined && ts.some(getKeywordCompletions(0 /* None */), function (c) { return c.name === name; })) {
+                return {
+                    name: name,
+                    kind: "keyword" /* keyword */,
+                    kindModifiers: "" /* none */,
+                    displayParts: [ts.displayPart(name, ts.SymbolDisplayPartKind.keyword)],
+                    documentation: undefined,
+                    tags: undefined,
+                    codeActions: undefined,
+                    source: undefined,
+                };
+            }
+            return undefined;
+        }
+        Completions.getCompletionEntryDetails = getCompletionEntryDetails;
+        function getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, checker, host, compilerOptions, sourceFile, rulesProvider) {
+            var symbolOriginInfo = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
+            if (!symbolOriginInfo) {
+                return undefined;
+            }
+            var moduleSymbol = symbolOriginInfo.moduleSymbol, isDefaultExport = symbolOriginInfo.isDefaultExport;
+            return ts.codefix.getCodeActionForImport(moduleSymbol, {
+                host: host,
+                checker: checker,
+                newLineCharacter: host.getNewLine(),
+                compilerOptions: compilerOptions,
+                sourceFile: sourceFile,
+                rulesProvider: rulesProvider,
+                symbolName: symbol.name,
+                getCanonicalFileName: ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false),
+                symbolToken: undefined,
+                kind: isDefaultExport ? 1 /* Default */ : 0 /* Named */,
+            });
+        }
+        function getCompletionEntrySymbol(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles) {
+            var completion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
+            return completion && completion.symbol;
+        }
+        Completions.getCompletionEntrySymbol = getCompletionEntrySymbol;
+        function getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles) {
+            var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
+            var request;
+            var start = ts.timestamp();
+            var currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853
+            // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.)
+            log("getCompletionData: Get current token: " + (ts.timestamp() - start));
+            start = ts.timestamp();
+            // Completion not allowed inside comments, bail out if this is the case
+            var insideComment = ts.isInComment(sourceFile, position, currentToken);
+            log("getCompletionData: Is inside comment: " + (ts.timestamp() - start));
+            var insideJsDocTagTypeExpression = false;
+            if (insideComment) {
+                if (ts.hasDocComment(sourceFile, position)) {
+                    if (sourceFile.text.charCodeAt(position - 1) === 64 /* at */) {
+                        // The current position is next to the '@' sign, when no tag name being provided yet.
+                        // Provide a full list of tag names
+                        request = { kind: "JsDocTagName" };
+                    }
+                    else {
+                        // When completion is requested without "@", we will have check to make sure that
+                        // there are no comments prefix the request position. We will only allow "*" and space.
+                        // e.g
+                        //   /** |c| /*
+                        //
+                        //   /**
+                        //     |c|
+                        //    */
+                        //
+                        //   /**
+                        //    * |c|
+                        //    */
+                        //
+                        //   /**
+                        //    *         |c|
+                        //    */
+                        var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
+                        if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) {
+                            request = { kind: "JsDocTag" };
+                        }
+                    }
+                }
+                // Completion should work inside certain JsDoc tags. For example:
+                //     /** @type {number | string} */
+                // Completion should work in the brackets
+                var tag = getJsDocTagAtPosition(currentToken, position);
+                if (tag) {
+                    if (tag.tagName.pos <= position && position <= tag.tagName.end) {
+                        request = { kind: "JsDocTagName" };
+                    }
+                    if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === 267 /* JSDocTypeExpression */) {
+                        currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true);
+                        if (!currentToken ||
+                            (!ts.isDeclarationName(currentToken) &&
+                                (currentToken.parent.kind !== 284 /* JSDocPropertyTag */ ||
+                                    currentToken.parent.name !== currentToken))) {
+                            // Use as type location if inside tag's type expression
+                            insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression);
+                        }
+                    }
+                    if (ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) {
+                        request = { kind: "JsDocParameterName", tag: tag };
+                    }
+                }
+                if (request) {
+                    return {
+                        symbols: undefined,
+                        isGlobalCompletion: false,
+                        isMemberCompletion: false,
+                        allowStringLiteral: false,
+                        isNewIdentifierLocation: false,
+                        location: undefined,
+                        isRightOfDot: false,
+                        request: request,
+                        keywordFilters: 0 /* None */,
+                        symbolToOriginInfoMap: undefined,
+                    };
+                }
+                if (!insideJsDocTagTypeExpression) {
+                    // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
+                    // comment or the plain text part of a jsDoc comment, so no completion should be available
+                    log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
+                    return undefined;
+                }
+            }
+            start = ts.timestamp();
+            var previousToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression);
+            log("getCompletionData: Get previous token 1: " + (ts.timestamp() - start));
+            // The decision to provide completion depends on the contextToken, which is determined through the previousToken.
+            // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
+            var contextToken = previousToken;
+            // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
+            // Skip this partial identifier and adjust the contextToken to the token that precedes it.
+            if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) {
+                var start_4 = ts.timestamp();
+                contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression);
+                log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_4));
+            }
+            // Find the node where completion is requested on.
+            // Also determine whether we are trying to complete with members of that node
+            // or attributes of a JSX tag.
+            var node = currentToken;
+            var isRightOfDot = false;
+            var isRightOfOpenTag = false;
+            var isStartingCloseTag = false;
+            var location = ts.getTouchingPropertyName(sourceFile, position, insideJsDocTagTypeExpression); // TODO: GH#15853
+            if (contextToken) {
+                // Bail out if this is a known invalid completion location
+                if (isCompletionListBlocker(contextToken)) {
+                    log("Returning an empty list because completion was requested in an invalid position.");
+                    return undefined;
+                }
+                var parent = contextToken.parent;
+                if (contextToken.kind === 23 /* DotToken */) {
+                    if (parent.kind === 179 /* PropertyAccessExpression */) {
+                        node = contextToken.parent.expression;
+                        isRightOfDot = true;
+                    }
+                    else if (parent.kind === 143 /* QualifiedName */) {
+                        node = contextToken.parent.left;
+                        isRightOfDot = true;
+                    }
+                    else {
+                        // There is nothing that precedes the dot, so this likely just a stray character
+                        // or leading into a '...' token. Just bail out instead.
+                        return undefined;
+                    }
+                }
+                else if (sourceFile.languageVariant === 1 /* JSX */) {
+                    // <UI.Test /* completion position */ />
+                    // If the tagname is a property access expression, we will then walk up to the top most of property access expression.
+                    // Then, try to get a JSX container and its associated attributes type.
+                    if (parent && parent.kind === 179 /* PropertyAccessExpression */) {
+                        contextToken = parent;
+                        parent = parent.parent;
+                    }
+                    switch (parent.kind) {
+                        case 252 /* JsxClosingElement */:
+                            if (contextToken.kind === 41 /* SlashToken */) {
+                                isStartingCloseTag = true;
+                                location = contextToken;
+                            }
+                            break;
+                        case 194 /* BinaryExpression */:
+                            if (!(parent.left.flags & 32768 /* ThisNodeHasError */)) {
+                                // It has a left-hand side, so we're not in an opening JSX tag.
+                                break;
+                            }
+                        // falls through
+                        case 250 /* JsxSelfClosingElement */:
+                        case 249 /* JsxElement */:
+                        case 251 /* JsxOpeningElement */:
+                            if (contextToken.kind === 27 /* LessThanToken */) {
+                                isRightOfOpenTag = true;
+                                location = contextToken;
+                            }
+                            break;
+                    }
+                }
+            }
+            var semanticStart = ts.timestamp();
+            var isGlobalCompletion = false;
+            var isMemberCompletion;
+            var allowStringLiteral = false;
+            var isNewIdentifierLocation;
+            var keywordFilters = 0 /* None */;
+            var symbols = [];
+            var symbolToOriginInfoMap = [];
+            if (isRightOfDot) {
+                getTypeScriptMemberSymbols();
+            }
+            else if (isRightOfOpenTag) {
+                var tagSymbols = typeChecker.getJsxIntrinsicTagNames();
+                if (tryGetGlobalSymbols()) {
+                    symbols = tagSymbols.concat(symbols.filter(function (s) { return !!(s.flags & (107455 /* Value */ | 2097152 /* Alias */)); }));
+                }
+                else {
+                    symbols = tagSymbols;
+                }
+                isMemberCompletion = true;
+                isNewIdentifierLocation = false;
+            }
+            else if (isStartingCloseTag) {
+                var tagName = contextToken.parent.parent.openingElement.tagName;
+                var tagSymbol = typeChecker.getSymbolAtLocation(tagName);
+                if (!typeChecker.isUnknownSymbol(tagSymbol)) {
+                    symbols = [tagSymbol];
+                }
+                isMemberCompletion = true;
+                isNewIdentifierLocation = false;
+            }
+            else {
+                // For JavaScript or TypeScript, if we're not after a dot, then just try to get the
+                // global symbols in scope.  These results should be valid for either language as
+                // the set of symbols that can be referenced from this location.
+                if (!tryGetGlobalSymbols()) {
+                    return undefined;
+                }
+            }
+            log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart));
+            return { symbols: symbols, isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, allowStringLiteral: allowStringLiteral, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request: request, keywordFilters: keywordFilters, symbolToOriginInfoMap: symbolToOriginInfoMap };
+            function isTagWithTypeExpression(tag) {
+                switch (tag.kind) {
+                    case 279 /* JSDocParameterTag */:
+                    case 284 /* JSDocPropertyTag */:
+                    case 280 /* JSDocReturnTag */:
+                    case 281 /* JSDocTypeTag */:
+                    case 283 /* JSDocTypedefTag */:
+                        return true;
+                }
+            }
+            function getTypeScriptMemberSymbols() {
+                // Right of dot member completion list
+                isGlobalCompletion = false;
+                isMemberCompletion = true;
+                isNewIdentifierLocation = false;
+                // Since this is qualified name check its a type node location
+                var isTypeLocation = insideJsDocTagTypeExpression || ts.isPartOfTypeNode(node.parent);
+                var isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node);
+                if (ts.isEntityName(node)) {
+                    var symbol = typeChecker.getSymbolAtLocation(node);
+                    if (symbol) {
+                        symbol = ts.skipAlias(symbol, typeChecker);
+                        if (symbol.flags & (1536 /* Module */ | 384 /* Enum */)) {
+                            // Extract module or enum members
+                            var exportedSymbols = typeChecker.getExportsOfModule(symbol);
+                            var isValidValueAccess_1 = function (symbol) { return typeChecker.isValidPropertyAccess((node.parent), symbol.name); };
+                            var isValidTypeAccess_1 = function (symbol) { return symbolCanBeReferencedAtTypeLocation(symbol); };
+                            var isValidAccess = isRhsOfImportDeclaration ?
+                                // Any kind is allowed when dotting off namespace in internal import equals declaration
+                                function (symbol) { return isValidTypeAccess_1(symbol) || isValidValueAccess_1(symbol); } :
+                                isTypeLocation ? isValidTypeAccess_1 : isValidValueAccess_1;
+                            for (var _i = 0, exportedSymbols_1 = exportedSymbols; _i < exportedSymbols_1.length; _i++) {
+                                var symbol_2 = exportedSymbols_1[_i];
+                                if (isValidAccess(symbol_2)) {
+                                    symbols.push(symbol_2);
+                                }
+                            }
+                            // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods).
+                            if (!isTypeLocation && symbol.declarations.some(function (d) { return d.kind !== 265 /* SourceFile */ && d.kind !== 233 /* ModuleDeclaration */ && d.kind !== 232 /* EnumDeclaration */; })) {
+                                addTypeProperties(typeChecker.getTypeOfSymbolAtLocation(symbol, node));
+                            }
+                            return;
+                        }
+                    }
+                }
+                if (!isTypeLocation) {
+                    addTypeProperties(typeChecker.getTypeAtLocation(node));
+                }
+            }
+            function addTypeProperties(type) {
+                // Filter private properties
+                for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) {
+                    var symbol = _a[_i];
+                    if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) {
+                        symbols.push(symbol);
+                    }
+                }
+                if (isJavaScriptFile && type.flags & 65536 /* Union */) {
+                    // In javascript files, for union types, we don't just get the members that
+                    // the individual types have in common, we also include all the members that
+                    // each individual type has.  This is because we're going to add all identifiers
+                    // anyways.  So we might as well elevate the members that were at least part
+                    // of the individual types to a higher status since we know what they are.
+                    var unionType = type;
+                    for (var _b = 0, _c = unionType.types; _b < _c.length; _b++) {
+                        var elementType = _c[_b];
+                        addTypeProperties(elementType);
+                    }
+                }
+            }
+            function tryGetGlobalSymbols() {
+                var objectLikeContainer;
+                var namedImportsOrExports;
+                var classLikeContainer;
+                var jsxContainer;
+                if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
+                    return tryGetObjectLikeCompletionSymbols(objectLikeContainer);
+                }
+                if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) {
+                    // cursor is in an import clause
+                    // try to show exported member for imported module
+                    return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
+                }
+                if (tryGetConstructorLikeCompletionContainer(contextToken)) {
+                    // no members, only keywords
+                    isMemberCompletion = false;
+                    // Declaring new property/method/accessor
+                    isNewIdentifierLocation = true;
+                    // Has keywords for constructor parameter
+                    keywordFilters = 2 /* ConstructorParameterKeywords */;
+                    return true;
+                }
+                if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
+                    // cursor inside class declaration
+                    getGetClassLikeCompletionSymbols(classLikeContainer);
+                    return true;
+                }
+                if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
+                    var attrsType = void 0;
+                    if ((jsxContainer.kind === 250 /* JsxSelfClosingElement */) || (jsxContainer.kind === 251 /* JsxOpeningElement */)) {
+                        // Cursor is inside a JSX self-closing element or opening element
+                        attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
+                        if (attrsType) {
+                            symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
+                            isMemberCompletion = true;
+                            isNewIdentifierLocation = false;
+                            return true;
+                        }
+                    }
+                }
+                // Get all entities in the current scope.
+                isMemberCompletion = false;
+                isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
+                if (previousToken !== contextToken) {
+                    ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
+                }
+                // We need to find the node that will give us an appropriate scope to begin
+                // aggregating completion candidates. This is achieved in 'getScopeNode'
+                // by finding the first node that encompasses a position, accounting for whether a node
+                // is "complete" to decide whether a position belongs to the node.
+                //
+                // However, at the end of an identifier, we are interested in the scope of the identifier
+                // itself, but fall outside of the identifier. For instance:
+                //
+                //      xyz => x$
+                //
+                // the cursor is outside of both the 'x' and the arrow function 'xyz => x',
+                // so 'xyz' is not returned in our results.
+                //
+                // We define 'adjustedPosition' so that we may appropriately account for
+                // being at the end of an identifier. The intention is that if requesting completion
+                // at the end of an identifier, it should be effectively equivalent to requesting completion
+                // anywhere inside/at the beginning of the identifier. So in the previous case, the
+                // 'adjustedPosition' will work as if requesting completion in the following:
+                //
+                //      xyz => $x
+                //
+                // If previousToken !== contextToken, then
+                //   - 'contextToken' was adjusted to the token prior to 'previousToken'
+                //      because we were at the end of an identifier.
+                //   - 'previousToken' is defined.
+                var adjustedPosition = previousToken !== contextToken ?
+                    previousToken.getStart() :
+                    position;
+                var scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
+                if (scopeNode) {
+                    isGlobalCompletion =
+                        scopeNode.kind === 265 /* SourceFile */ ||
+                            scopeNode.kind === 196 /* TemplateExpression */ ||
+                            scopeNode.kind === 256 /* JsxExpression */ ||
+                            ts.isStatement(scopeNode);
+                }
+                var symbolMeanings = 793064 /* Type */ | 107455 /* Value */ | 1920 /* Namespace */ | 2097152 /* Alias */;
+                symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
+                getSymbolsFromOtherSourceFileExports(symbols, previousToken && ts.isIdentifier(previousToken) ? previousToken.text : "");
+                filterGlobalCompletion(symbols);
+                return true;
+            }
+            function filterGlobalCompletion(symbols) {
+                ts.filterMutate(symbols, function (symbol) {
+                    if (!ts.isSourceFile(location)) {
+                        // export = /**/ here we want to get all meanings, so any symbol is ok
+                        if (ts.isExportAssignment(location.parent)) {
+                            return true;
+                        }
+                        // This is an alias, follow what it aliases
+                        if (symbol && symbol.flags & 2097152 /* Alias */) {
+                            symbol = typeChecker.getAliasedSymbol(symbol);
+                        }
+                        // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
+                        if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) {
+                            return !!(symbol.flags & 1920 /* Namespace */);
+                        }
+                        if (insideJsDocTagTypeExpression ||
+                            (!isContextTokenValueLocation(contextToken) &&
+                                (ts.isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)))) {
+                            // Its a type, but you can reach it by namespace.type as well
+                            return symbolCanBeReferencedAtTypeLocation(symbol);
+                        }
+                    }
+                    // expressions are value space (which includes the value namespaces)
+                    return !!(ts.getCombinedLocalAndExportSymbolFlags(symbol) & 107455 /* Value */);
+                });
+            }
+            function isContextTokenValueLocation(contextToken) {
+                return contextToken &&
+                    contextToken.kind === 103 /* TypeOfKeyword */ &&
+                    contextToken.parent.kind === 162 /* TypeQuery */;
+            }
+            function isContextTokenTypeLocation(contextToken) {
+                if (contextToken) {
+                    var parentKind = contextToken.parent.kind;
+                    switch (contextToken.kind) {
+                        case 56 /* ColonToken */:
+                            return parentKind === 149 /* PropertyDeclaration */ ||
+                                parentKind === 148 /* PropertySignature */ ||
+                                parentKind === 146 /* Parameter */ ||
+                                parentKind === 226 /* VariableDeclaration */ ||
+                                ts.isFunctionLikeKind(parentKind);
+                        case 58 /* EqualsToken */:
+                            return parentKind === 231 /* TypeAliasDeclaration */;
+                        case 118 /* AsKeyword */:
+                            return parentKind === 202 /* AsExpression */;
+                    }
+                }
+            }
+            function symbolCanBeReferencedAtTypeLocation(symbol) {
+                symbol = symbol.exportSymbol || symbol;
+                // This is an alias, follow what it aliases
+                symbol = ts.skipAlias(symbol, typeChecker);
+                if (symbol.flags & 793064 /* Type */) {
+                    return true;
+                }
+                if (symbol.flags & 1536 /* Module */) {
+                    var exportedSymbols = typeChecker.getExportsOfModule(symbol);
+                    // If the exported symbols contains type,
+                    // symbol can be referenced at locations where type is allowed
+                    return ts.forEach(exportedSymbols, symbolCanBeReferencedAtTypeLocation);
+                }
+            }
+            function getSymbolsFromOtherSourceFileExports(symbols, tokenText) {
+                var tokenTextLowerCase = tokenText.toLowerCase();
+                ts.codefix.forEachExternalModule(typeChecker, allSourceFiles, function (moduleSymbol) {
+                    if (moduleSymbol === sourceFile.symbol) {
+                        return;
+                    }
+                    for (var _i = 0, _a = typeChecker.getExportsOfModule(moduleSymbol); _i < _a.length; _i++) {
+                        var symbol = _a[_i];
+                        var name = symbol.name;
+                        var isDefaultExport = name === "default";
+                        if (isDefaultExport) {
+                            var localSymbol = ts.getLocalSymbolForExportDefault(symbol);
+                            if (localSymbol) {
+                                symbol = localSymbol;
+                                name = localSymbol.name;
+                            }
+                        }
+                        if (symbol.declarations && symbol.declarations.some(function (d) { return ts.isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier; })) {
+                            // Don't add a completion for a re-export, only for the original.
+                            continue;
+                        }
+                        if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) {
+                            symbols.push(symbol);
+                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { moduleSymbol: moduleSymbol, isDefaultExport: isDefaultExport };
+                        }
+                    }
+                });
+            }
+            /**
+             * True if you could remove some characters in `a` to get `b`.
+             * E.g., true for "abcdef" and "bdf".
+             * But not true for "abcdef" and "dbf".
+             */
+            function stringContainsCharactersInOrder(str, characters) {
+                if (characters.length === 0) {
+                    return true;
+                }
+                var characterIndex = 0;
+                for (var strIndex = 0; strIndex < str.length; strIndex++) {
+                    if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) {
+                        characterIndex++;
+                        if (characterIndex === characters.length) {
+                            return true;
+                        }
+                    }
+                }
+                // Did not find all characters
+                return false;
+            }
+            /**
+             * Finds the first node that "embraces" the position, so that one may
+             * accurately aggregate locals from the closest containing scope.
+             */
+            function getScopeNode(initialToken, position, sourceFile) {
+                var scope = initialToken;
+                while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) {
+                    scope = scope.parent;
+                }
+                return scope;
+            }
+            function isCompletionListBlocker(contextToken) {
+                var start = ts.timestamp();
+                var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
+                    isSolelyIdentifierDefinitionLocation(contextToken) ||
+                    isDotOfNumericLiteral(contextToken) ||
+                    isInJsxText(contextToken);
+                log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start));
+                return result;
+            }
+            function isInJsxText(contextToken) {
+                if (contextToken.kind === 10 /* JsxText */) {
+                    return true;
+                }
+                if (contextToken.kind === 29 /* GreaterThanToken */ && contextToken.parent) {
+                    if (contextToken.parent.kind === 251 /* JsxOpeningElement */) {
+                        return true;
+                    }
+                    if (contextToken.parent.kind === 252 /* JsxClosingElement */ || contextToken.parent.kind === 250 /* JsxSelfClosingElement */) {
+                        return contextToken.parent.parent && contextToken.parent.parent.kind === 249 /* JsxElement */;
+                    }
+                }
+                return false;
+            }
+            function isNewIdentifierDefinitionLocation(previousToken) {
+                if (previousToken) {
+                    var containingNodeKind = previousToken.parent.kind;
+                    switch (previousToken.kind) {
+                        case 26 /* CommaToken */:
+                            return containingNodeKind === 181 /* CallExpression */ // func( a, |
+                                || containingNodeKind === 152 /* Constructor */ // constructor( a, |   /* public, protected, private keywords are allowed here, so show completion */
+                                || containingNodeKind === 182 /* NewExpression */ // new C(a, |
+                                || containingNodeKind === 177 /* ArrayLiteralExpression */ // [a, |
+                                || containingNodeKind === 194 /* BinaryExpression */ // const x = (a, |
+                                || containingNodeKind === 160 /* FunctionType */; // var x: (s: string, list|
+                        case 19 /* OpenParenToken */:
+                            return containingNodeKind === 181 /* CallExpression */ // func( |
+                                || containingNodeKind === 152 /* Constructor */ // constructor( |
+                                || containingNodeKind === 182 /* NewExpression */ // new C(a|
+                                || containingNodeKind === 185 /* ParenthesizedExpression */ // const x = (a|
+                                || containingNodeKind === 168 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */
+                        case 21 /* OpenBracketToken */:
+                            return containingNodeKind === 177 /* ArrayLiteralExpression */ // [ |
+                                || containingNodeKind === 157 /* IndexSignature */ // [ | : string ]
+                                || containingNodeKind === 144 /* ComputedPropertyName */; // [ |    /* this can become an index signature */
+                        case 128 /* ModuleKeyword */: // module |
+                        case 129 /* NamespaceKeyword */:// namespace |
+                            return true;
+                        case 23 /* DotToken */:
+                            return containingNodeKind === 233 /* ModuleDeclaration */; // module A.|
+                        case 17 /* OpenBraceToken */:
+                            return containingNodeKind === 229 /* ClassDeclaration */; // class A{ |
+                        case 58 /* EqualsToken */:
+                            return containingNodeKind === 226 /* VariableDeclaration */ // const x = a|
+                                || containingNodeKind === 194 /* BinaryExpression */; // x = a|
+                        case 14 /* TemplateHead */:
+                            return containingNodeKind === 196 /* TemplateExpression */; // `aa ${|
+                        case 15 /* TemplateMiddle */:
+                            return containingNodeKind === 205 /* TemplateSpan */; // `aa ${10} dd ${|
+                        case 114 /* PublicKeyword */:
+                        case 112 /* PrivateKeyword */:
+                        case 113 /* ProtectedKeyword */:
+                            return containingNodeKind === 149 /* PropertyDeclaration */; // class A{ public |
+                    }
+                    // Previous token may have been a keyword that was converted to an identifier.
+                    switch (previousToken.getText()) {
+                        case "public":
+                        case "protected":
+                        case "private":
+                            return true;
+                    }
+                }
+                return false;
+            }
+            function isInStringOrRegularExpressionOrTemplateLiteral(contextToken) {
+                if (contextToken.kind === 9 /* StringLiteral */
+                    || contextToken.kind === 12 /* RegularExpressionLiteral */
+                    || ts.isTemplateLiteralKind(contextToken.kind)) {
+                    var start_5 = contextToken.getStart();
+                    var end = contextToken.getEnd();
+                    // To be "in" one of these literals, the position has to be:
+                    //   1. entirely within the token text.
+                    //   2. at the end position of an unterminated token.
+                    //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
+                    if (start_5 < position && position < end) {
+                        return true;
+                    }
+                    if (position === end) {
+                        return !!contextToken.isUnterminated
+                            || contextToken.kind === 12 /* RegularExpressionLiteral */;
+                    }
+                }
+                return false;
+            }
+            /**
+             * Aggregates relevant symbols for completion in object literals and object binding patterns.
+             * Relevant symbols are stored in the captured 'symbols' variable.
+             *
+             * @returns true if 'symbols' was successfully populated; false otherwise.
+             */
+            function tryGetObjectLikeCompletionSymbols(objectLikeContainer) {
+                // We're looking up possible property names from contextual/inferred/declared type.
+                isMemberCompletion = true;
+                allowStringLiteral = true;
+                var typeMembers;
+                var existingMembers;
+                if (objectLikeContainer.kind === 178 /* ObjectLiteralExpression */) {
+                    // We are completing on contextual types, but may also include properties
+                    // other than those within the declared type.
+                    isNewIdentifierLocation = true;
+                    var typeForObject = typeChecker.getContextualType(objectLikeContainer);
+                    if (!typeForObject)
+                        return false;
+                    typeMembers = getPropertiesForCompletion(typeForObject, typeChecker);
+                    existingMembers = objectLikeContainer.properties;
+                }
+                else {
+                    ts.Debug.assert(objectLikeContainer.kind === 174 /* ObjectBindingPattern */);
+                    // We are *only* completing on properties from the type being destructured.
+                    isNewIdentifierLocation = false;
+                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
+                    if (!ts.isVariableLike(rootDeclaration))
+                        throw ts.Debug.fail("Root declaration is not variable-like.");
+                    // We don't want to complete using the type acquired by the shape
+                    // of the binding pattern; we are only interested in types acquired
+                    // through type declaration or inference.
+                    // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
+                    // type of parameter will flow in from the contextual type of the function
+                    var canGetType = rootDeclaration.initializer || rootDeclaration.type || rootDeclaration.parent.parent.kind === 216 /* ForOfStatement */;
+                    if (!canGetType && rootDeclaration.kind === 146 /* Parameter */) {
+                        if (ts.isExpression(rootDeclaration.parent)) {
+                            canGetType = !!typeChecker.getContextualType(rootDeclaration.parent);
+                        }
+                        else if (rootDeclaration.parent.kind === 151 /* MethodDeclaration */ || rootDeclaration.parent.kind === 154 /* SetAccessor */) {
+                            canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent);
+                        }
+                    }
+                    if (canGetType) {
+                        var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
+                        if (!typeForObject)
+                            return false;
+                        // In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
+                        typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); });
+                        existingMembers = objectLikeContainer.elements;
+                    }
+                }
+                if (typeMembers && typeMembers.length > 0) {
+                    // Add filtered items to the completion list
+                    symbols = filterObjectMembersList(typeMembers, existingMembers);
+                }
+                return true;
+            }
+            /**
+             * Aggregates relevant symbols for completion in import clauses and export clauses
+             * whose declarations have a module specifier; for instance, symbols will be aggregated for
+             *
+             *      import { | } from "moduleName";
+             *      export { a as foo, | } from "moduleName";
+             *
+             * but not for
+             *
+             *      export { | };
+             *
+             * Relevant symbols are stored in the captured 'symbols' variable.
+             *
+             * @returns true if 'symbols' was successfully populated; false otherwise.
+             */
+            function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) {
+                var declarationKind = namedImportsOrExports.kind === 241 /* NamedImports */ ?
+                    238 /* ImportDeclaration */ :
+                    244 /* ExportDeclaration */;
+                var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind);
+                var moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
+                if (!moduleSpecifier) {
+                    return false;
+                }
+                isMemberCompletion = true;
+                isNewIdentifierLocation = false;
+                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier);
+                if (!moduleSpecifierSymbol) {
+                    symbols = ts.emptyArray;
+                    return true;
+                }
+                var exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
+                symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements);
+                return true;
+            }
+            /**
+             * Aggregates relevant symbols for completion in class declaration
+             * Relevant symbols are stored in the captured 'symbols' variable.
+             */
+            function getGetClassLikeCompletionSymbols(classLikeDeclaration) {
+                // We're looking up possible property names from parent type.
+                isMemberCompletion = true;
+                // Declaring new property/method/accessor
+                isNewIdentifierLocation = true;
+                // Has keywords for class elements
+                keywordFilters = 1 /* ClassElementKeywords */;
+                var baseTypeNode = ts.getClassExtendsHeritageClauseElement(classLikeDeclaration);
+                var implementsTypeNodes = ts.getClassImplementsHeritageClauseElements(classLikeDeclaration);
+                if (baseTypeNode || implementsTypeNodes) {
+                    var classElement = contextToken.parent;
+                    var classElementModifierFlags = ts.isClassElement(classElement) && ts.getModifierFlags(classElement);
+                    // If this is context token is not something we are editing now, consider if this would lead to be modifier
+                    if (contextToken.kind === 71 /* Identifier */ && !isCurrentlyEditingNode(contextToken)) {
+                        switch (contextToken.getText()) {
+                            case "private":
+                                classElementModifierFlags = classElementModifierFlags | 8 /* Private */;
+                                break;
+                            case "static":
+                                classElementModifierFlags = classElementModifierFlags | 32 /* Static */;
+                                break;
+                        }
+                    }
+                    // No member list for private methods
+                    if (!(classElementModifierFlags & 8 /* Private */)) {
+                        var baseClassTypeToGetPropertiesFrom = void 0;
+                        if (baseTypeNode) {
+                            baseClassTypeToGetPropertiesFrom = typeChecker.getTypeAtLocation(baseTypeNode);
+                            if (classElementModifierFlags & 32 /* Static */) {
+                                // Use static class to get property symbols from
+                                baseClassTypeToGetPropertiesFrom = typeChecker.getTypeOfSymbolAtLocation(baseClassTypeToGetPropertiesFrom.symbol, classLikeDeclaration);
+                            }
+                        }
+                        var implementedInterfaceTypePropertySymbols = (classElementModifierFlags & 32 /* Static */) ?
+                            ts.emptyArray :
+                            ts.flatMap(implementsTypeNodes || ts.emptyArray, function (typeNode) { return typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)); });
+                        // List of property symbols of base type that are not private and already implemented
+                        symbols = filterClassMembersList(baseClassTypeToGetPropertiesFrom ?
+                            typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) :
+                            ts.emptyArray, implementedInterfaceTypePropertySymbols, classLikeDeclaration.members, classElementModifierFlags);
+                    }
+                }
+            }
+            /**
+             * Returns the immediate owning object literal or binding pattern of a context token,
+             * on the condition that one exists and that the context implies completion should be given.
+             */
+            function tryGetObjectLikeCompletionContainer(contextToken) {
+                if (contextToken) {
+                    switch (contextToken.kind) {
+                        case 17 /* OpenBraceToken */: // const x = { |
+                        case 26 /* CommaToken */:// const x = { a: 0, |
+                            var parent = contextToken.parent;
+                            if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) {
+                                return parent;
+                            }
+                            break;
+                    }
+                }
+                return undefined;
+            }
+            /**
+             * Returns the containing list of named imports or exports of a context token,
+             * on the condition that one exists and that the context implies completion should be given.
+             */
+            function tryGetNamedImportsOrExportsForCompletion(contextToken) {
+                if (contextToken) {
+                    switch (contextToken.kind) {
+                        case 17 /* OpenBraceToken */: // import { |
+                        case 26 /* CommaToken */:// import { a as 0, |
+                            switch (contextToken.parent.kind) {
+                                case 241 /* NamedImports */:
+                                case 245 /* NamedExports */:
+                                    return contextToken.parent;
+                            }
+                    }
+                }
+                return undefined;
+            }
+            function isFromClassElementDeclaration(node) {
+                return ts.isClassElement(node.parent) && ts.isClassLike(node.parent.parent);
+            }
+            function isParameterOfConstructorDeclaration(node) {
+                return ts.isParameter(node) && ts.isConstructorDeclaration(node.parent);
+            }
+            function isConstructorParameterCompletion(node) {
+                return node.parent &&
+                    isParameterOfConstructorDeclaration(node.parent) &&
+                    (isConstructorParameterCompletionKeyword(node.kind) || ts.isDeclarationName(node));
+            }
+            /**
+             * Returns the immediate owning class declaration of a context token,
+             * on the condition that one exists and that the context implies completion should be given.
+             */
+            function tryGetClassLikeCompletionContainer(contextToken) {
+                if (contextToken) {
+                    switch (contextToken.kind) {
+                        case 17 /* OpenBraceToken */:// class c { |
+                            if (ts.isClassLike(contextToken.parent)) {
+                                return contextToken.parent;
+                            }
+                            break;
+                        // class c {getValue(): number, | }
+                        case 26 /* CommaToken */:
+                            if (ts.isClassLike(contextToken.parent)) {
+                                return contextToken.parent;
+                            }
+                            break;
+                        // class c {getValue(): number; | }
+                        case 25 /* SemicolonToken */:
+                        // class c { method() { } | }
+                        case 18 /* CloseBraceToken */:
+                            if (ts.isClassLike(location)) {
+                                return location;
+                            }
+                            // class c { method() { } b| }
+                            if (isFromClassElementDeclaration(location) &&
+                                location.parent.name === location) {
+                                return location.parent.parent;
+                            }
+                            break;
+                        default:
+                            if (isFromClassElementDeclaration(contextToken) &&
+                                (isClassMemberCompletionKeyword(contextToken.kind) ||
+                                    isClassMemberCompletionKeywordText(contextToken.getText()))) {
+                                return contextToken.parent.parent;
+                            }
+                    }
+                }
+                // class c { method() { } | method2() { } }
+                if (location && location.kind === 286 /* SyntaxList */ && ts.isClassLike(location.parent)) {
+                    return location.parent;
+                }
+                return undefined;
+            }
+            /**
+             * Returns the immediate owning class declaration of a context token,
+             * on the condition that one exists and that the context implies completion should be given.
+             */
+            function tryGetConstructorLikeCompletionContainer(contextToken) {
+                if (contextToken) {
+                    switch (contextToken.kind) {
+                        case 19 /* OpenParenToken */:
+                        case 26 /* CommaToken */:
+                            return ts.isConstructorDeclaration(contextToken.parent) && contextToken.parent;
+                        default:
+                            if (isConstructorParameterCompletion(contextToken)) {
+                                return contextToken.parent.parent;
+                            }
+                    }
+                }
+                return undefined;
+            }
+            function tryGetContainingJsxElement(contextToken) {
+                if (contextToken) {
+                    var parent = contextToken.parent;
+                    switch (contextToken.kind) {
+                        case 28 /* LessThanSlashToken */:
+                        case 41 /* SlashToken */:
+                        case 71 /* Identifier */:
+                        case 179 /* PropertyAccessExpression */:
+                        case 254 /* JsxAttributes */:
+                        case 253 /* JsxAttribute */:
+                        case 255 /* JsxSpreadAttribute */:
+                            if (parent && (parent.kind === 250 /* JsxSelfClosingElement */ || parent.kind === 251 /* JsxOpeningElement */)) {
+                                return parent;
+                            }
+                            else if (parent.kind === 253 /* JsxAttribute */) {
+                                // Currently we parse JsxOpeningLikeElement as:
+                                //      JsxOpeningLikeElement
+                                //          attributes: JsxAttributes
+                                //             properties: NodeArray<JsxAttributeLike>
+                                return parent.parent.parent;
+                            }
+                            break;
+                        // The context token is the closing } or " of an attribute, which means
+                        // its parent is a JsxExpression, whose parent is a JsxAttribute,
+                        // whose parent is a JsxOpeningLikeElement
+                        case 9 /* StringLiteral */:
+                            if (parent && ((parent.kind === 253 /* JsxAttribute */) || (parent.kind === 255 /* JsxSpreadAttribute */))) {
+                                // Currently we parse JsxOpeningLikeElement as:
+                                //      JsxOpeningLikeElement
+                                //          attributes: JsxAttributes
+                                //             properties: NodeArray<JsxAttributeLike>
+                                return parent.parent.parent;
+                            }
+                            break;
+                        case 18 /* CloseBraceToken */:
+                            if (parent &&
+                                parent.kind === 256 /* JsxExpression */ &&
+                                parent.parent && parent.parent.kind === 253 /* JsxAttribute */) {
+                                // Currently we parse JsxOpeningLikeElement as:
+                                //      JsxOpeningLikeElement
+                                //          attributes: JsxAttributes
+                                //             properties: NodeArray<JsxAttributeLike>
+                                //                  each JsxAttribute can have initializer as JsxExpression
+                                return parent.parent.parent.parent;
+                            }
+                            if (parent && parent.kind === 255 /* JsxSpreadAttribute */) {
+                                // Currently we parse JsxOpeningLikeElement as:
+                                //      JsxOpeningLikeElement
+                                //          attributes: JsxAttributes
+                                //             properties: NodeArray<JsxAttributeLike>
+                                return parent.parent.parent;
+                            }
+                            break;
+                    }
+                }
+                return undefined;
+            }
+            /**
+             * @returns true if we are certain that the currently edited location must define a new location; false otherwise.
+             */
+            function isSolelyIdentifierDefinitionLocation(contextToken) {
+                var containingNodeKind = contextToken.parent.kind;
+                switch (contextToken.kind) {
+                    case 26 /* CommaToken */:
+                        return containingNodeKind === 226 /* VariableDeclaration */ ||
+                            containingNodeKind === 227 /* VariableDeclarationList */ ||
+                            containingNodeKind === 208 /* VariableStatement */ ||
+                            containingNodeKind === 232 /* EnumDeclaration */ || // enum a { foo, |
+                            isFunctionLikeButNotConstructor(containingNodeKind) ||
+                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A<T, |
+                            containingNodeKind === 175 /* ArrayBindingPattern */ || // var [x, y|
+                            containingNodeKind === 231 /* TypeAliasDeclaration */ || // type Map, K, |
+                            // class A<T, |
+                            // var C = class D<T, |
+                            (ts.isClassLike(contextToken.parent) &&
+                                contextToken.parent.typeParameters &&
+                                contextToken.parent.typeParameters.end >= contextToken.pos);
+                    case 23 /* DotToken */:
+                        return containingNodeKind === 175 /* ArrayBindingPattern */; // var [.|
+                    case 56 /* ColonToken */:
+                        return containingNodeKind === 176 /* BindingElement */; // var {x :html|
+                    case 21 /* OpenBracketToken */:
+                        return containingNodeKind === 175 /* ArrayBindingPattern */; // var [x|
+                    case 19 /* OpenParenToken */:
+                        return containingNodeKind === 260 /* CatchClause */ ||
+                            isFunctionLikeButNotConstructor(containingNodeKind);
+                    case 17 /* OpenBraceToken */:
+                        return containingNodeKind === 232 /* EnumDeclaration */ || // enum a { |
+                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface a { |
+                            containingNodeKind === 163 /* TypeLiteral */; // const x : { |
+                    case 25 /* SemicolonToken */:
+                        return containingNodeKind === 148 /* PropertySignature */ &&
+                            contextToken.parent && contextToken.parent.parent &&
+                            (contextToken.parent.parent.kind === 230 /* InterfaceDeclaration */ || // interface a { f; |
+                                contextToken.parent.parent.kind === 163 /* TypeLiteral */); // const x : { a; |
+                    case 27 /* LessThanToken */:
+                        return containingNodeKind === 229 /* ClassDeclaration */ || // class A< |
+                            containingNodeKind === 199 /* ClassExpression */ || // var C = class D< |
+                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A< |
+                            containingNodeKind === 231 /* TypeAliasDeclaration */ || // type List< |
+                            ts.isFunctionLikeKind(containingNodeKind);
+                    case 115 /* StaticKeyword */:
+                        return containingNodeKind === 149 /* PropertyDeclaration */ && !ts.isClassLike(contextToken.parent.parent);
+                    case 24 /* DotDotDotToken */:
+                        return containingNodeKind === 146 /* Parameter */ ||
+                            (contextToken.parent && contextToken.parent.parent &&
+                                contextToken.parent.parent.kind === 175 /* ArrayBindingPattern */); // var [...z|
+                    case 114 /* PublicKeyword */:
+                    case 112 /* PrivateKeyword */:
+                    case 113 /* ProtectedKeyword */:
+                        return containingNodeKind === 146 /* Parameter */ && !ts.isConstructorDeclaration(contextToken.parent.parent);
+                    case 118 /* AsKeyword */:
+                        return containingNodeKind === 242 /* ImportSpecifier */ ||
+                            containingNodeKind === 246 /* ExportSpecifier */ ||
+                            containingNodeKind === 240 /* NamespaceImport */;
+                    case 125 /* GetKeyword */:
+                    case 135 /* SetKeyword */:
+                        if (isFromClassElementDeclaration(contextToken)) {
+                            return false;
+                        }
+                    // falls through
+                    case 75 /* ClassKeyword */:
+                    case 83 /* EnumKeyword */:
+                    case 109 /* InterfaceKeyword */:
+                    case 89 /* FunctionKeyword */:
+                    case 104 /* VarKeyword */:
+                    case 91 /* ImportKeyword */:
+                    case 110 /* LetKeyword */:
+                    case 76 /* ConstKeyword */:
+                    case 116 /* YieldKeyword */:
+                    case 138 /* TypeKeyword */:// type htm|
+                        return true;
+                }
+                // If the previous token is keyword correspoding to class member completion keyword
+                // there will be completion available here
+                if (isClassMemberCompletionKeywordText(contextToken.getText()) &&
+                    isFromClassElementDeclaration(contextToken)) {
+                    return false;
+                }
+                if (isConstructorParameterCompletion(contextToken)) {
+                    // constructor parameter completion is available only if
+                    // - its modifier of the constructor parameter or
+                    // - its name of the parameter and not being edited
+                    // eg. constructor(a |<- this shouldnt show completion
+                    if (!ts.isIdentifier(contextToken) ||
+                        isConstructorParameterCompletionKeywordText(contextToken.getText()) ||
+                        isCurrentlyEditingNode(contextToken)) {
+                        return false;
+                    }
+                }
+                // Previous token may have been a keyword that was converted to an identifier.
+                switch (contextToken.getText()) {
+                    case "abstract":
+                    case "async":
+                    case "class":
+                    case "const":
+                    case "declare":
+                    case "enum":
+                    case "function":
+                    case "interface":
+                    case "let":
+                    case "private":
+                    case "protected":
+                    case "public":
+                    case "static":
+                    case "var":
+                    case "yield":
+                        return true;
+                }
+                return ts.isDeclarationName(contextToken) && !ts.isJsxAttribute(contextToken.parent);
+            }
+            function isFunctionLikeButNotConstructor(kind) {
+                return ts.isFunctionLikeKind(kind) && kind !== 152 /* Constructor */;
+            }
+            function isDotOfNumericLiteral(contextToken) {
+                if (contextToken.kind === 8 /* NumericLiteral */) {
+                    var text = contextToken.getFullText();
+                    return text.charAt(text.length - 1) === ".";
+                }
+                return false;
+            }
+            /**
+             * Filters out completion suggestions for named imports or exports.
+             *
+             * @param exportsOfModule          The list of symbols which a module exposes.
+             * @param namedImportsOrExports    The list of existing import/export specifiers in the import/export clause.
+             *
+             * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports
+             *          do not occur at the current position and have not otherwise been typed.
+             */
+            function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) {
+                var existingImportsOrExports = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, namedImportsOrExports_1 = namedImportsOrExports; _i < namedImportsOrExports_1.length; _i++) {
+                    var element = namedImportsOrExports_1[_i];
+                    // If this is the current item we are editing right now, do not filter it out
+                    if (isCurrentlyEditingNode(element)) {
+                        continue;
+                    }
+                    var name = element.propertyName || element.name;
+                    existingImportsOrExports.set(name.escapedText, true);
+                }
+                if (existingImportsOrExports.size === 0) {
+                    return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default"; });
+                }
+                return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName); });
+            }
+            /**
+             * Filters out completion suggestions for named imports or exports.
+             *
+             * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations
+             *          do not occur at the current position and have not otherwise been typed.
+             */
+            function filterObjectMembersList(contextualMemberSymbols, existingMembers) {
+                if (!existingMembers || existingMembers.length === 0) {
+                    return contextualMemberSymbols;
+                }
+                var existingMemberNames = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, existingMembers_1 = existingMembers; _i < existingMembers_1.length; _i++) {
+                    var m = existingMembers_1[_i];
+                    // Ignore omitted expressions for missing members
+                    if (m.kind !== 261 /* PropertyAssignment */ &&
+                        m.kind !== 262 /* ShorthandPropertyAssignment */ &&
+                        m.kind !== 176 /* BindingElement */ &&
+                        m.kind !== 151 /* MethodDeclaration */ &&
+                        m.kind !== 153 /* GetAccessor */ &&
+                        m.kind !== 154 /* SetAccessor */) {
+                        continue;
+                    }
+                    // If this is the current item we are editing right now, do not filter it out
+                    if (isCurrentlyEditingNode(m)) {
+                        continue;
+                    }
+                    var existingName = void 0;
+                    if (m.kind === 176 /* BindingElement */ && m.propertyName) {
+                        // include only identifiers in completion list
+                        if (m.propertyName.kind === 71 /* Identifier */) {
+                            existingName = m.propertyName.escapedText;
+                        }
+                    }
+                    else {
+                        // TODO: Account for computed property name
+                        // NOTE: if one only performs this step when m.name is an identifier,
+                        // things like '__proto__' are not filtered out.
+                        var name = ts.getNameOfDeclaration(m);
+                        existingName = ts.getEscapedTextOfIdentifierOrLiteral(name);
+                    }
+                    existingMemberNames.set(existingName, true);
+                }
+                return ts.filter(contextualMemberSymbols, function (m) { return !existingMemberNames.get(m.escapedName); });
+            }
+            /**
+             * Filters out completion suggestions for class elements.
+             *
+             * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
+             */
+            function filterClassMembersList(baseSymbols, implementingTypeSymbols, existingMembers, currentClassElementModifierFlags) {
+                var existingMemberNames = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, existingMembers_2 = existingMembers; _i < existingMembers_2.length; _i++) {
+                    var m = existingMembers_2[_i];
+                    // Ignore omitted expressions for missing members
+                    if (m.kind !== 149 /* PropertyDeclaration */ &&
+                        m.kind !== 151 /* MethodDeclaration */ &&
+                        m.kind !== 153 /* GetAccessor */ &&
+                        m.kind !== 154 /* SetAccessor */) {
+                        continue;
+                    }
+                    // If this is the current item we are editing right now, do not filter it out
+                    if (isCurrentlyEditingNode(m)) {
+                        continue;
+                    }
+                    // Dont filter member even if the name matches if it is declared private in the list
+                    if (ts.hasModifier(m, 8 /* Private */)) {
+                        continue;
+                    }
+                    // do not filter it out if the static presence doesnt match
+                    var mIsStatic = ts.hasModifier(m, 32 /* Static */);
+                    var currentElementIsStatic = !!(currentClassElementModifierFlags & 32 /* Static */);
+                    if ((mIsStatic && !currentElementIsStatic) ||
+                        (!mIsStatic && currentElementIsStatic)) {
+                        continue;
+                    }
+                    var existingName = ts.getPropertyNameForPropertyNameNode(m.name);
+                    if (existingName) {
+                        existingMemberNames.set(existingName, true);
+                    }
+                }
+                var result = [];
+                addPropertySymbols(baseSymbols, 8 /* Private */);
+                addPropertySymbols(implementingTypeSymbols, 24 /* NonPublicAccessibilityModifier */);
+                return result;
+                function addPropertySymbols(properties, inValidModifierFlags) {
+                    for (var _i = 0, properties_12 = properties; _i < properties_12.length; _i++) {
+                        var property = properties_12[_i];
+                        if (isValidProperty(property, inValidModifierFlags)) {
+                            result.push(property);
+                        }
+                    }
+                }
+                function isValidProperty(propertySymbol, inValidModifierFlags) {
+                    return !existingMemberNames.get(propertySymbol.escapedName) &&
+                        propertySymbol.getDeclarations() &&
+                        !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags);
+                }
+            }
+            /**
+             * Filters out completion suggestions from 'symbols' according to existing JSX attributes.
+             *
+             * @returns Symbols to be suggested in a JSX element, barring those whose attributes
+             *          do not occur at the current position and have not otherwise been typed.
+             */
+            function filterJsxAttributes(symbols, attributes) {
+                var seenNames = ts.createUnderscoreEscapedMap();
+                for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) {
+                    var attr = attributes_1[_i];
+                    // If this is the current item we are editing right now, do not filter it out
+                    if (isCurrentlyEditingNode(attr)) {
+                        continue;
+                    }
+                    if (attr.kind === 253 /* JsxAttribute */) {
+                        seenNames.set(attr.name.escapedText, true);
+                    }
+                }
+                return ts.filter(symbols, function (a) { return !seenNames.get(a.escapedName); });
+            }
+            function isCurrentlyEditingNode(node) {
+                return node.getStart() <= position && position <= node.getEnd();
+            }
+        }
+        /**
+         * Get the name to be display in completion from a given symbol.
+         *
+         * @return undefined if the name is of external module
+         */
+        function getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral) {
+            var name = symbol.name;
+            if (!name)
+                return undefined;
+            // First check of the displayName is not external module; if it is an external module, it is not valid entry
+            if (symbol.flags & 1920 /* Namespace */) {
+                var firstCharCode = name.charCodeAt(0);
+                if (ts.isSingleOrDoubleQuote(firstCharCode)) {
+                    // If the symbol is external module, don't show it in the completion list
+                    // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
+                    return undefined;
+                }
+            }
+            return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral);
+        }
+        /**
+         * Get a displayName from a given for completion list, performing any necessary quotes stripping
+         * and checking whether the name is valid identifier name.
+         */
+        function getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral) {
+            // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
+            // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
+            // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid.
+            // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name.
+            if (performCharacterChecks && !ts.isIdentifierText(name, target)) {
+                // TODO: GH#18169
+                return allowStringLiteral ? JSON.stringify(name) : undefined;
+            }
+            return name;
+        }
+        // A cache of completion entries for keywords, these do not change between sessions
+        var _keywordCompletions = [];
+        function getKeywordCompletions(keywordFilter) {
+            var completions = _keywordCompletions[keywordFilter];
+            if (completions) {
+                return completions;
+            }
+            return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter);
+            function generateKeywordCompletions(keywordFilter) {
+                switch (keywordFilter) {
+                    case 0 /* None */:
+                        return getAllKeywordCompletions();
+                    case 1 /* ClassElementKeywords */:
+                        return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText);
+                    case 2 /* ConstructorParameterKeywords */:
+                        return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText);
+                }
+            }
+            function getAllKeywordCompletions() {
+                var allKeywordsCompletions = [];
+                for (var i = 72 /* FirstKeyword */; i <= 142 /* LastKeyword */; i++) {
+                    allKeywordsCompletions.push({
+                        name: ts.tokenToString(i),
+                        kind: "keyword" /* keyword */,
+                        kindModifiers: "" /* none */,
+                        sortText: "0"
+                    });
+                }
+                return allKeywordsCompletions;
+            }
+            function getFilteredKeywordCompletions(filterFn) {
+                return ts.filter(getKeywordCompletions(0 /* None */), function (entry) { return filterFn(entry.name); });
+            }
+        }
+        function isClassMemberCompletionKeyword(kind) {
+            switch (kind) {
+                case 114 /* PublicKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 117 /* AbstractKeyword */:
+                case 115 /* StaticKeyword */:
+                case 123 /* ConstructorKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                case 125 /* GetKeyword */:
+                case 135 /* SetKeyword */:
+                case 120 /* AsyncKeyword */:
+                    return true;
+            }
+        }
+        function isClassMemberCompletionKeywordText(text) {
+            return isClassMemberCompletionKeyword(ts.stringToToken(text));
+        }
+        function isConstructorParameterCompletionKeyword(kind) {
+            switch (kind) {
+                case 114 /* PublicKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                    return true;
+            }
+        }
+        function isConstructorParameterCompletionKeywordText(text) {
+            return isConstructorParameterCompletionKeyword(ts.stringToToken(text));
+        }
+        function isEqualityExpression(node) {
+            return ts.isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
+        }
+        function isEqualityOperatorKind(kind) {
+            return kind === 32 /* EqualsEqualsToken */ ||
+                kind === 33 /* ExclamationEqualsToken */ ||
+                kind === 34 /* EqualsEqualsEqualsToken */ ||
+                kind === 35 /* ExclamationEqualsEqualsToken */;
+        }
+        /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
+        function getJsDocTagAtPosition(node, position) {
+            var jsDoc = getJsDocHavingNode(node).jsDoc;
+            if (!jsDoc)
+                return undefined;
+            for (var _i = 0, jsDoc_1 = jsDoc; _i < jsDoc_1.length; _i++) {
+                var _a = jsDoc_1[_i], pos = _a.pos, end = _a.end, tags = _a.tags;
+                if (!tags || position < pos || position > end)
+                    continue;
+                for (var i = tags.length - 1; i >= 0; i--) {
+                    var tag = tags[i];
+                    if (position >= tag.pos) {
+                        return tag;
+                    }
+                }
+            }
+        }
+        function getJsDocHavingNode(node) {
+            if (!ts.isToken(node))
+                return node;
+            switch (node.kind) {
+                case 104 /* VarKeyword */:
+                case 110 /* LetKeyword */:
+                case 76 /* ConstKeyword */:
+                    // if the current token is var, let or const, skip the VariableDeclarationList
+                    return node.parent.parent;
+                default:
+                    return node.parent;
+            }
+        }
+        /**
+         * Gets all properties on a type, but if that type is a union of several types,
+         * tries to only include those types which declare properties, not methods.
+         * This ensures that we don't try providing completions for all the methods on e.g. Array.
+         */
+        function getPropertiesForCompletion(type, checker) {
+            if (!(type.flags & 65536 /* Union */)) {
+                return checker.getPropertiesOfType(type);
+            }
+            var types = type.types;
+            var filteredTypes = types.filter(function (memberType) { return !(memberType.flags & 8190 /* Primitive */ || checker.isArrayLikeType(memberType)); });
+            // If there are no property-only types, just provide completions for every type as usual.
+            return checker.getAllPossiblePropertiesOfTypes(filteredTypes);
+        }
+    })(Completions = ts.Completions || (ts.Completions = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var DocumentHighlights;
+    (function (DocumentHighlights) {
+        function getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch) {
+            var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
+            // Note that getTouchingWord indicates failure by returning the sourceFile node.
+            if (node === sourceFile)
+                return undefined;
+            ts.Debug.assert(node.parent !== undefined);
+            if (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent)) {
+                // For a JSX element, just highlight the matching tag, not all references.
+                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
+                var highlightSpans = [openingElement, closingElement].map(function (_a) {
+                    var tagName = _a.tagName;
+                    return getHighlightSpanForNode(tagName, sourceFile);
+                });
+                return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
+            }
+            return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile);
+        }
+        DocumentHighlights.getDocumentHighlights = getDocumentHighlights;
+        function getHighlightSpanForNode(node, sourceFile) {
+            return {
+                fileName: sourceFile.fileName,
+                textSpan: ts.createTextSpanFromNode(node, sourceFile),
+                kind: "none" /* none */
+            };
+        }
+        function getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) {
+            var referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(node, program, sourceFilesToSearch, cancellationToken);
+            return referenceEntries && convertReferencedSymbols(referenceEntries);
+        }
+        function convertReferencedSymbols(referenceEntries) {
+            var fileNameToDocumentHighlights = ts.createMap();
+            for (var _i = 0, referenceEntries_1 = referenceEntries; _i < referenceEntries_1.length; _i++) {
+                var entry = referenceEntries_1[_i];
+                var _a = ts.FindAllReferences.toHighlightSpan(entry), fileName = _a.fileName, span_12 = _a.span;
+                var highlightSpans = fileNameToDocumentHighlights.get(fileName);
+                if (!highlightSpans) {
+                    fileNameToDocumentHighlights.set(fileName, highlightSpans = []);
+                }
+                highlightSpans.push(span_12);
+            }
+            return ts.arrayFrom(fileNameToDocumentHighlights.entries(), function (_a) {
+                var fileName = _a[0], highlightSpans = _a[1];
+                return ({ fileName: fileName, highlightSpans: highlightSpans });
+            });
+        }
+        function getSyntacticDocumentHighlights(node, sourceFile) {
+            var highlightSpans = getHighlightSpans(node, sourceFile);
+            if (!highlightSpans || highlightSpans.length === 0) {
+                return undefined;
+            }
+            return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
+        }
+        // returns true if 'node' is defined and has a matching 'kind'.
+        function hasKind(node, kind) {
+            return node !== undefined && node.kind === kind;
+        }
+        // Null-propagating 'parent' function.
+        function parent(node) {
+            return node && node.parent;
+        }
+        function getHighlightSpans(node, sourceFile) {
+            if (!node) {
+                return undefined;
+            }
+            switch (node.kind) {
+                case 90 /* IfKeyword */:
+                case 82 /* ElseKeyword */:
+                    if (hasKind(node.parent, 211 /* IfStatement */)) {
+                        return getIfElseOccurrences(node.parent, sourceFile);
+                    }
+                    break;
+                case 96 /* ReturnKeyword */:
+                    if (hasKind(node.parent, 219 /* ReturnStatement */)) {
+                        return highlightSpans(getReturnOccurrences(node.parent));
+                    }
+                    break;
+                case 100 /* ThrowKeyword */:
+                    if (hasKind(node.parent, 223 /* ThrowStatement */)) {
+                        return highlightSpans(getThrowOccurrences(node.parent));
+                    }
+                    break;
+                case 102 /* TryKeyword */:
+                case 74 /* CatchKeyword */:
+                case 87 /* FinallyKeyword */:
+                    var tryStatement = node.kind === 74 /* CatchKeyword */ ? parent(parent(node)) : parent(node);
+                    if (hasKind(tryStatement, 224 /* TryStatement */)) {
+                        return highlightSpans(getTryCatchFinallyOccurrences(tryStatement, sourceFile));
+                    }
+                    break;
+                case 98 /* SwitchKeyword */:
+                    if (hasKind(node.parent, 221 /* SwitchStatement */)) {
+                        return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent));
+                    }
+                    break;
+                case 73 /* CaseKeyword */:
+                case 79 /* DefaultKeyword */:
+                    if (hasKind(parent(parent(parent(node))), 221 /* SwitchStatement */)) {
+                        return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent.parent.parent));
+                    }
+                    break;
+                case 72 /* BreakKeyword */:
+                case 77 /* ContinueKeyword */:
+                    if (hasKind(node.parent, 218 /* BreakStatement */) || hasKind(node.parent, 217 /* ContinueStatement */)) {
+                        return highlightSpans(getBreakOrContinueStatementOccurrences(node.parent));
+                    }
+                    break;
+                case 88 /* ForKeyword */:
+                    if (hasKind(node.parent, 214 /* ForStatement */) ||
+                        hasKind(node.parent, 215 /* ForInStatement */) ||
+                        hasKind(node.parent, 216 /* ForOfStatement */)) {
+                        return highlightSpans(getLoopBreakContinueOccurrences(node.parent));
+                    }
+                    break;
+                case 106 /* WhileKeyword */:
+                case 81 /* DoKeyword */:
+                    if (hasKind(node.parent, 213 /* WhileStatement */) || hasKind(node.parent, 212 /* DoStatement */)) {
+                        return highlightSpans(getLoopBreakContinueOccurrences(node.parent));
+                    }
+                    break;
+                case 123 /* ConstructorKeyword */:
+                    if (hasKind(node.parent, 152 /* Constructor */)) {
+                        return highlightSpans(getConstructorOccurrences(node.parent));
+                    }
+                    break;
+                case 125 /* GetKeyword */:
+                case 135 /* SetKeyword */:
+                    if (hasKind(node.parent, 153 /* GetAccessor */) || hasKind(node.parent, 154 /* SetAccessor */)) {
+                        return highlightSpans(getGetAndSetOccurrences(node.parent));
+                    }
+                    break;
+                default:
+                    if (ts.isModifierKind(node.kind) && node.parent &&
+                        (ts.isDeclaration(node.parent) || node.parent.kind === 208 /* VariableStatement */)) {
+                        return highlightSpans(getModifierOccurrences(node.kind, node.parent));
+                    }
+            }
+            function highlightSpans(nodes) {
+                return nodes && nodes.map(function (node) { return getHighlightSpanForNode(node, sourceFile); });
+            }
+        }
+        /**
+         * Aggregates all throw-statements within this node *without* crossing
+         * into function boundaries and try-blocks with catch-clauses.
+         */
+        function aggregateOwnedThrowStatements(node) {
+            var statementAccumulator = [];
+            aggregate(node);
+            return statementAccumulator;
+            function aggregate(node) {
+                if (node.kind === 223 /* ThrowStatement */) {
+                    statementAccumulator.push(node);
+                }
+                else if (node.kind === 224 /* TryStatement */) {
+                    var tryStatement = node;
+                    if (tryStatement.catchClause) {
+                        aggregate(tryStatement.catchClause);
+                    }
+                    else {
+                        // Exceptions thrown within a try block lacking a catch clause
+                        // are "owned" in the current context.
+                        aggregate(tryStatement.tryBlock);
+                    }
+                    if (tryStatement.finallyBlock) {
+                        aggregate(tryStatement.finallyBlock);
+                    }
+                }
+                else if (!ts.isFunctionLike(node)) {
+                    ts.forEachChild(node, aggregate);
+                }
+            }
+        }
+        /**
+         * For lack of a better name, this function takes a throw statement and returns the
+         * nearest ancestor that is a try-block (whose try statement has a catch clause),
+         * function-block, or source file.
+         */
+        function getThrowStatementOwner(throwStatement) {
+            var child = throwStatement;
+            while (child.parent) {
+                var parent_2 = child.parent;
+                if (ts.isFunctionBlock(parent_2) || parent_2.kind === 265 /* SourceFile */) {
+                    return parent_2;
+                }
+                // A throw-statement is only owned by a try-statement if the try-statement has
+                // a catch clause, and if the throw-statement occurs within the try block.
+                if (parent_2.kind === 224 /* TryStatement */) {
+                    var tryStatement = parent_2;
+                    if (tryStatement.tryBlock === child && tryStatement.catchClause) {
+                        return child;
+                    }
+                }
+                child = parent_2;
+            }
+            return undefined;
+        }
+        function aggregateAllBreakAndContinueStatements(node) {
+            var statementAccumulator = [];
+            aggregate(node);
+            return statementAccumulator;
+            function aggregate(node) {
+                if (node.kind === 218 /* BreakStatement */ || node.kind === 217 /* ContinueStatement */) {
+                    statementAccumulator.push(node);
+                }
+                else if (!ts.isFunctionLike(node)) {
+                    ts.forEachChild(node, aggregate);
+                }
+            }
+        }
+        function ownsBreakOrContinueStatement(owner, statement) {
+            var actualOwner = getBreakOrContinueOwner(statement);
+            return actualOwner && actualOwner === owner;
+        }
+        function getBreakOrContinueOwner(statement) {
+            for (var node = statement.parent; node; node = node.parent) {
+                switch (node.kind) {
+                    case 221 /* SwitchStatement */:
+                        if (statement.kind === 217 /* ContinueStatement */) {
+                            continue;
+                        }
+                    // falls through
+                    case 214 /* ForStatement */:
+                    case 215 /* ForInStatement */:
+                    case 216 /* ForOfStatement */:
+                    case 213 /* WhileStatement */:
+                    case 212 /* DoStatement */:
+                        if (!statement.label || isLabeledBy(node, statement.label.text)) {
+                            return node;
+                        }
+                        break;
+                    default:
+                        // Don't cross function boundaries.
+                        if (ts.isFunctionLike(node)) {
+                            return undefined;
+                        }
+                        break;
+                }
+            }
+            return undefined;
+        }
+        function getModifierOccurrences(modifier, declaration) {
+            // Make sure we only highlight the keyword when it makes sense to do so.
+            if (!isLegalModifier(modifier, declaration)) {
+                return undefined;
+            }
+            var modifierFlag = ts.modifierToFlag(modifier);
+            return ts.mapDefined(getNodesToSearchForModifier(declaration, modifierFlag), function (node) {
+                if (ts.getModifierFlags(node) & modifierFlag) {
+                    var mod = ts.find(node.modifiers, function (m) { return m.kind === modifier; });
+                    ts.Debug.assert(!!mod);
+                    return mod;
+                }
+            });
+        }
+        function getNodesToSearchForModifier(declaration, modifierFlag) {
+            var container = declaration.parent;
+            switch (container.kind) {
+                case 234 /* ModuleBlock */:
+                case 265 /* SourceFile */:
+                case 207 /* Block */:
+                case 257 /* CaseClause */:
+                case 258 /* DefaultClause */:
+                    // Container is either a class declaration or the declaration is a classDeclaration
+                    if (modifierFlag & 128 /* Abstract */) {
+                        return declaration.members.concat([declaration]);
+                    }
+                    else {
+                        return container.statements;
+                    }
+                case 152 /* Constructor */:
+                    return container.parameters.concat(container.parent.members);
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                    var nodes = container.members;
+                    // If we're an accessibility modifier, we're in an instance member and should search
+                    // the constructor's parameter list for instance members as well.
+                    if (modifierFlag & 28 /* AccessibilityModifier */) {
+                        var constructor = ts.find(container.members, ts.isConstructorDeclaration);
+                        if (constructor) {
+                            return nodes.concat(constructor.parameters);
+                        }
+                    }
+                    else if (modifierFlag & 128 /* Abstract */) {
+                        return nodes.concat([container]);
+                    }
+                    return nodes;
+                default:
+                    ts.Debug.fail("Invalid container kind.");
+            }
+        }
+        function isLegalModifier(modifier, declaration) {
+            var container = declaration.parent;
+            switch (modifier) {
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 114 /* PublicKeyword */:
+                    switch (container.kind) {
+                        case 229 /* ClassDeclaration */:
+                        case 199 /* ClassExpression */:
+                            return true;
+                        case 152 /* Constructor */:
+                            return declaration.kind === 146 /* Parameter */;
+                        default:
+                            return false;
+                    }
+                case 115 /* StaticKeyword */:
+                    return container.kind === 229 /* ClassDeclaration */ || container.kind === 199 /* ClassExpression */;
+                case 84 /* ExportKeyword */:
+                case 124 /* DeclareKeyword */:
+                    return container.kind === 234 /* ModuleBlock */ || container.kind === 265 /* SourceFile */;
+                case 117 /* AbstractKeyword */:
+                    return container.kind === 229 /* ClassDeclaration */ || declaration.kind === 229 /* ClassDeclaration */;
+                default:
+                    return false;
+            }
+        }
+        function pushKeywordIf(keywordList, token) {
+            var expected = [];
+            for (var _i = 2; _i < arguments.length; _i++) {
+                expected[_i - 2] = arguments[_i];
+            }
+            if (token && ts.contains(expected, token.kind)) {
+                keywordList.push(token);
+                return true;
+            }
+            return false;
+        }
+        function getGetAndSetOccurrences(accessorDeclaration) {
+            var keywords = [];
+            tryPushAccessorKeyword(accessorDeclaration.symbol, 153 /* GetAccessor */);
+            tryPushAccessorKeyword(accessorDeclaration.symbol, 154 /* SetAccessor */);
+            return keywords;
+            function tryPushAccessorKeyword(accessorSymbol, accessorKind) {
+                var accessor = ts.getDeclarationOfKind(accessorSymbol, accessorKind);
+                if (accessor) {
+                    ts.forEach(accessor.getChildren(), function (child) { return pushKeywordIf(keywords, child, 125 /* GetKeyword */, 135 /* SetKeyword */); });
+                }
+            }
+        }
+        function getConstructorOccurrences(constructorDeclaration) {
+            var declarations = constructorDeclaration.symbol.getDeclarations();
+            var keywords = [];
+            ts.forEach(declarations, function (declaration) {
+                ts.forEach(declaration.getChildren(), function (token) {
+                    return pushKeywordIf(keywords, token, 123 /* ConstructorKeyword */);
+                });
+            });
+            return keywords;
+        }
+        function getLoopBreakContinueOccurrences(loopNode) {
+            var keywords = [];
+            if (pushKeywordIf(keywords, loopNode.getFirstToken(), 88 /* ForKeyword */, 106 /* WhileKeyword */, 81 /* DoKeyword */)) {
+                // If we succeeded and got a do-while loop, then start looking for a 'while' keyword.
+                if (loopNode.kind === 212 /* DoStatement */) {
+                    var loopTokens = loopNode.getChildren();
+                    for (var i = loopTokens.length - 1; i >= 0; i--) {
+                        if (pushKeywordIf(keywords, loopTokens[i], 106 /* WhileKeyword */)) {
+                            break;
+                        }
+                    }
+                }
+            }
+            var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement);
+            ts.forEach(breaksAndContinues, function (statement) {
+                if (ownsBreakOrContinueStatement(loopNode, statement)) {
+                    pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */, 77 /* ContinueKeyword */);
+                }
+            });
+            return keywords;
+        }
+        function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) {
+            var owner = getBreakOrContinueOwner(breakOrContinueStatement);
+            if (owner) {
+                switch (owner.kind) {
+                    case 214 /* ForStatement */:
+                    case 215 /* ForInStatement */:
+                    case 216 /* ForOfStatement */:
+                    case 212 /* DoStatement */:
+                    case 213 /* WhileStatement */:
+                        return getLoopBreakContinueOccurrences(owner);
+                    case 221 /* SwitchStatement */:
+                        return getSwitchCaseDefaultOccurrences(owner);
+                }
+            }
+            return undefined;
+        }
+        function getSwitchCaseDefaultOccurrences(switchStatement) {
+            var keywords = [];
+            pushKeywordIf(keywords, switchStatement.getFirstToken(), 98 /* SwitchKeyword */);
+            // Go through each clause in the switch statement, collecting the 'case'/'default' keywords.
+            ts.forEach(switchStatement.caseBlock.clauses, function (clause) {
+                pushKeywordIf(keywords, clause.getFirstToken(), 73 /* CaseKeyword */, 79 /* DefaultKeyword */);
+                var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause);
+                ts.forEach(breaksAndContinues, function (statement) {
+                    if (ownsBreakOrContinueStatement(switchStatement, statement)) {
+                        pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */);
+                    }
+                });
+            });
+            return keywords;
+        }
+        function getTryCatchFinallyOccurrences(tryStatement, sourceFile) {
+            var keywords = [];
+            pushKeywordIf(keywords, tryStatement.getFirstToken(), 102 /* TryKeyword */);
+            if (tryStatement.catchClause) {
+                pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 74 /* CatchKeyword */);
+            }
+            if (tryStatement.finallyBlock) {
+                var finallyKeyword = ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile);
+                pushKeywordIf(keywords, finallyKeyword, 87 /* FinallyKeyword */);
+            }
+            return keywords;
+        }
+        function getThrowOccurrences(throwStatement) {
+            var owner = getThrowStatementOwner(throwStatement);
+            if (!owner) {
+                return undefined;
+            }
+            var keywords = [];
+            ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
+                pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */);
+            });
+            // If the "owner" is a function, then we equate 'return' and 'throw' statements in their
+            // ability to "jump out" of the function, and include occurrences for both.
+            if (ts.isFunctionBlock(owner)) {
+                ts.forEachReturnStatement(owner, function (returnStatement) {
+                    pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */);
+                });
+            }
+            return keywords;
+        }
+        function getReturnOccurrences(returnStatement) {
+            var func = ts.getContainingFunction(returnStatement);
+            // If we didn't find a containing function with a block body, bail out.
+            if (!(func && hasKind(func.body, 207 /* Block */))) {
+                return undefined;
+            }
+            var keywords = [];
+            ts.forEachReturnStatement(func.body, function (returnStatement) {
+                pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */);
+            });
+            // Include 'throw' statements that do not occur within a try block.
+            ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
+                pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */);
+            });
+            return keywords;
+        }
+        function getIfElseOccurrences(ifStatement, sourceFile) {
+            var keywords = [];
+            // Traverse upwards through all parent if-statements linked by their else-branches.
+            while (hasKind(ifStatement.parent, 211 /* IfStatement */) && ifStatement.parent.elseStatement === ifStatement) {
+                ifStatement = ifStatement.parent;
+            }
+            // Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
+            while (ifStatement) {
+                var children = ifStatement.getChildren();
+                pushKeywordIf(keywords, children[0], 90 /* IfKeyword */);
+                // Generally the 'else' keyword is second-to-last, so we traverse backwards.
+                for (var i = children.length - 1; i >= 0; i--) {
+                    if (pushKeywordIf(keywords, children[i], 82 /* ElseKeyword */)) {
+                        break;
+                    }
+                }
+                if (!hasKind(ifStatement.elseStatement, 211 /* IfStatement */)) {
+                    break;
+                }
+                ifStatement = ifStatement.elseStatement;
+            }
+            var result = [];
+            // We'd like to highlight else/ifs together if they are only separated by whitespace
+            // (i.e. the keywords are separated by no comments, no newlines).
+            for (var i = 0; i < keywords.length; i++) {
+                if (keywords[i].kind === 82 /* ElseKeyword */ && i < keywords.length - 1) {
+                    var elseKeyword = keywords[i];
+                    var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword.
+                    var shouldCombindElseAndIf = true;
+                    // Avoid recalculating getStart() by iterating backwards.
+                    for (var j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) {
+                        if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) {
+                            shouldCombindElseAndIf = false;
+                            break;
+                        }
+                    }
+                    if (shouldCombindElseAndIf) {
+                        result.push({
+                            fileName: sourceFile.fileName,
+                            textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
+                            kind: "reference" /* reference */
+                        });
+                        i++; // skip the next keyword
+                        continue;
+                    }
+                }
+                // Ordinary case: just highlight the keyword.
+                result.push(getHighlightSpanForNode(keywords[i], sourceFile));
+            }
+            return result;
+        }
+        /**
+         * Whether or not a 'node' is preceded by a label of the given string.
+         * Note: 'node' cannot be a SourceFile.
+         */
+        function isLabeledBy(node, labelName) {
+            for (var owner = node.parent; owner.kind === 222 /* LabeledStatement */; owner = owner.parent) {
+                if (owner.label.escapedText === labelName) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    })(DocumentHighlights = ts.DocumentHighlights || (ts.DocumentHighlights = {}));
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+    function createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory) {
+        if (currentDirectory === void 0) { currentDirectory = ""; }
+        // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
+        // for those settings.
+        var buckets = ts.createMap();
+        var getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames);
+        function getKeyForCompilationSettings(settings) {
+            return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + "|" + settings.allowJs + "|" + settings.baseUrl + "|" + JSON.stringify(settings.typeRoots) + "|" + JSON.stringify(settings.rootDirs) + "|" + JSON.stringify(settings.paths);
+        }
+        function getBucketForCompilationSettings(key, createIfMissing) {
+            var bucket = buckets.get(key);
+            if (!bucket && createIfMissing) {
+                buckets.set(key, bucket = ts.createMap());
+            }
+            return bucket;
+        }
+        function reportStats() {
+            var bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) {
+                var entries = buckets.get(name);
+                var sourceFiles = [];
+                entries.forEach(function (entry, name) {
+                    sourceFiles.push({
+                        name: name,
+                        refCount: entry.languageServiceRefCount,
+                        references: entry.owners.slice(0)
+                    });
+                });
+                sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; });
+                return {
+                    bucket: name,
+                    sourceFiles: sourceFiles
+                };
+            });
+            return JSON.stringify(bucketInfoArray, undefined, 2);
+        }
+        function acquireDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
+            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+            var key = getKeyForCompilationSettings(compilationSettings);
+            return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
+        }
+        function acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
+            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind);
+        }
+        function updateDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
+            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+            var key = getKeyForCompilationSettings(compilationSettings);
+            return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
+        }
+        function updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
+            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ false, scriptKind);
+        }
+        function acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, acquiring, scriptKind) {
+            var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
+            var entry = bucket.get(path);
+            if (!entry) {
+                // Have never seen this file with these settings.  Create a new source file for it.
+                var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
+                entry = {
+                    sourceFile: sourceFile,
+                    languageServiceRefCount: 1,
+                    owners: []
+                };
+                bucket.set(path, entry);
+            }
+            else {
+                // We have an entry for this file.  However, it may be for a different version of
+                // the script snapshot.  If so, update it appropriately.  Otherwise, we can just
+                // return it as is.
+                if (entry.sourceFile.version !== version) {
+                    entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
+                }
+                // If we're acquiring, then this is the first time this LS is asking for this document.
+                // Increase our ref count so we know there's another LS using the document.  If we're
+                // not acquiring, then that means the LS is 'updating' the file instead, and that means
+                // it has already acquired the document previously.  As such, we do not need to increase
+                // the ref count.
+                if (acquiring) {
+                    entry.languageServiceRefCount++;
+                }
+            }
+            return entry.sourceFile;
+        }
+        function releaseDocument(fileName, compilationSettings) {
+            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+            var key = getKeyForCompilationSettings(compilationSettings);
+            return releaseDocumentWithKey(path, key);
+        }
+        function releaseDocumentWithKey(path, key) {
+            var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ false);
+            ts.Debug.assert(bucket !== undefined);
+            var entry = bucket.get(path);
+            entry.languageServiceRefCount--;
+            ts.Debug.assert(entry.languageServiceRefCount >= 0);
+            if (entry.languageServiceRefCount === 0) {
+                bucket.delete(path);
+            }
+        }
+        return {
+            acquireDocument: acquireDocument,
+            acquireDocumentWithKey: acquireDocumentWithKey,
+            updateDocument: updateDocument,
+            updateDocumentWithKey: updateDocumentWithKey,
+            releaseDocument: releaseDocument,
+            releaseDocumentWithKey: releaseDocumentWithKey,
+            reportStats: reportStats,
+            getKeyForCompilationSettings: getKeyForCompilationSettings
+        };
+    }
+    ts.createDocumentRegistry = createDocumentRegistry;
+})(ts || (ts = {}));
+/* Code for finding imports of an exported symbol. Used only by FindAllReferences. */
+/* @internal */
+var ts;
+(function (ts) {
+    var FindAllReferences;
+    (function (FindAllReferences) {
+        /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily.  */
+        function createImportTracker(sourceFiles, checker, cancellationToken) {
+            var allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken);
+            return function (exportSymbol, exportInfo, isForRename) {
+                var _a = getImportersForExport(sourceFiles, allDirectImports, exportInfo, checker, cancellationToken), directImports = _a.directImports, indirectUsers = _a.indirectUsers;
+                return __assign({ indirectUsers: indirectUsers }, getSearchesFromDirectImports(directImports, exportSymbol, exportInfo.exportKind, checker, isForRename));
+            };
+        }
+        FindAllReferences.createImportTracker = createImportTracker;
+        var ExportKind;
+        (function (ExportKind) {
+            ExportKind[ExportKind["Named"] = 0] = "Named";
+            ExportKind[ExportKind["Default"] = 1] = "Default";
+            ExportKind[ExportKind["ExportEquals"] = 2] = "ExportEquals";
+        })(ExportKind = FindAllReferences.ExportKind || (FindAllReferences.ExportKind = {}));
+        var ImportExport;
+        (function (ImportExport) {
+            ImportExport[ImportExport["Import"] = 0] = "Import";
+            ImportExport[ImportExport["Export"] = 1] = "Export";
+        })(ImportExport = FindAllReferences.ImportExport || (FindAllReferences.ImportExport = {}));
+        /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
+        function getImportersForExport(sourceFiles, allDirectImports, _a, checker, cancellationToken) {
+            var exportingModuleSymbol = _a.exportingModuleSymbol, exportKind = _a.exportKind;
+            var markSeenDirectImport = ts.nodeSeenTracker();
+            var markSeenIndirectUser = ts.nodeSeenTracker();
+            var directImports = [];
+            var isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports;
+            var indirectUserDeclarations = isAvailableThroughGlobal ? undefined : [];
+            handleDirectImports(exportingModuleSymbol);
+            return { directImports: directImports, indirectUsers: getIndirectUsers() };
+            function getIndirectUsers() {
+                if (isAvailableThroughGlobal) {
+                    // It has `export as namespace`, so anything could potentially use it.
+                    return sourceFiles;
+                }
+                // Module augmentations may use this module's exports without importing it.
+                for (var _i = 0, _a = exportingModuleSymbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    if (ts.isExternalModuleAugmentation(decl)) {
+                        addIndirectUser(decl);
+                    }
+                }
+                // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that.
+                return indirectUserDeclarations.map(ts.getSourceFileOfNode);
+            }
+            function handleDirectImports(exportingModuleSymbol) {
+                var theseDirectImports = getDirectImports(exportingModuleSymbol);
+                if (theseDirectImports) {
+                    for (var _i = 0, theseDirectImports_1 = theseDirectImports; _i < theseDirectImports_1.length; _i++) {
+                        var direct = theseDirectImports_1[_i];
+                        if (!markSeenDirectImport(direct)) {
+                            continue;
+                        }
+                        cancellationToken.throwIfCancellationRequested();
+                        switch (direct.kind) {
+                            case 181 /* CallExpression */:
+                                if (!isAvailableThroughGlobal) {
+                                    var parent = direct.parent;
+                                    if (exportKind === 2 /* ExportEquals */ && parent.kind === 226 /* VariableDeclaration */) {
+                                        var name = parent.name;
+                                        if (name.kind === 71 /* Identifier */) {
+                                            directImports.push(name);
+                                            break;
+                                        }
+                                    }
+                                    // Don't support re-exporting 'require()' calls, so just add a single indirect user.
+                                    addIndirectUser(direct.getSourceFile());
+                                }
+                                break;
+                            case 237 /* ImportEqualsDeclaration */:
+                                handleNamespaceImport(direct, direct.name, ts.hasModifier(direct, 1 /* Export */));
+                                break;
+                            case 238 /* ImportDeclaration */:
+                                var namedBindings = direct.importClause && direct.importClause.namedBindings;
+                                if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) {
+                                    handleNamespaceImport(direct, namedBindings.name);
+                                }
+                                else {
+                                    directImports.push(direct);
+                                }
+                                break;
+                            case 244 /* ExportDeclaration */:
+                                if (!direct.exportClause) {
+                                    // This is `export * from "foo"`, so imports of this module may import the export too.
+                                    handleDirectImports(getContainingModuleSymbol(direct, checker));
+                                }
+                                else {
+                                    // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports.
+                                    directImports.push(direct);
+                                }
+                                break;
+                        }
+                    }
+                }
+            }
+            function handleNamespaceImport(importDeclaration, name, isReExport) {
+                if (exportKind === 2 /* ExportEquals */) {
+                    // This is a direct import, not import-as-namespace.
+                    directImports.push(importDeclaration);
+                }
+                else if (!isAvailableThroughGlobal) {
+                    var sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration);
+                    ts.Debug.assert(sourceFileLike.kind === 265 /* SourceFile */ || sourceFileLike.kind === 233 /* ModuleDeclaration */);
+                    if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) {
+                        addIndirectUsers(sourceFileLike);
+                    }
+                    else {
+                        addIndirectUser(sourceFileLike);
+                    }
+                }
+            }
+            function addIndirectUser(sourceFileLike) {
+                ts.Debug.assert(!isAvailableThroughGlobal);
+                var isNew = markSeenIndirectUser(sourceFileLike);
+                if (isNew) {
+                    indirectUserDeclarations.push(sourceFileLike);
+                }
+                return isNew;
+            }
+            /** Adds a module and all of its transitive dependencies as possible indirect users. */
+            function addIndirectUsers(sourceFileLike) {
+                if (!addIndirectUser(sourceFileLike)) {
+                    return;
+                }
+                var moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol);
+                ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
+                var directImports = getDirectImports(moduleSymbol);
+                if (directImports) {
+                    for (var _i = 0, directImports_1 = directImports; _i < directImports_1.length; _i++) {
+                        var directImport = directImports_1[_i];
+                        addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport));
+                    }
+                }
+            }
+            function getDirectImports(moduleSymbol) {
+                return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString());
+            }
+        }
+        /**
+         * Given the set of direct imports of a module, we need to find which ones import the particular exported symbol.
+         * The returned `importSearches` will result in the entire source file being searched.
+         * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
+         */
+        function getSearchesFromDirectImports(directImports, exportSymbol, exportKind, checker, isForRename) {
+            var importSearches = [];
+            var singleReferences = [];
+            function addSearch(location, symbol) {
+                importSearches.push([location, symbol]);
+            }
+            if (directImports) {
+                for (var _i = 0, directImports_2 = directImports; _i < directImports_2.length; _i++) {
+                    var decl = directImports_2[_i];
+                    handleImport(decl);
+                }
+            }
+            return { importSearches: importSearches, singleReferences: singleReferences };
+            function handleImport(decl) {
+                if (decl.kind === 237 /* ImportEqualsDeclaration */) {
+                    if (isExternalModuleImportEquals(decl)) {
+                        handleNamespaceImportLike(decl.name);
+                    }
+                    return;
+                }
+                if (decl.kind === 71 /* Identifier */) {
+                    handleNamespaceImportLike(decl);
+                    return;
+                }
+                // Ignore if there's a grammar error
+                if (decl.moduleSpecifier.kind !== 9 /* StringLiteral */) {
+                    return;
+                }
+                if (decl.kind === 244 /* ExportDeclaration */) {
+                    searchForNamedImport(decl.exportClause);
+                    return;
+                }
+                var importClause = decl.importClause;
+                if (!importClause) {
+                    return;
+                }
+                var namedBindings = importClause.namedBindings;
+                if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) {
+                    handleNamespaceImportLike(namedBindings.name);
+                    return;
+                }
+                if (exportKind === 0 /* Named */) {
+                    searchForNamedImport(namedBindings);
+                }
+                else {
+                    // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals
+                    var name = importClause.name;
+                    // If a default import has the same name as the default export, allow to rename it.
+                    // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
+                    if (name && (!isForRename || name.escapedText === symbolName(exportSymbol))) {
+                        var defaultImportAlias = checker.getSymbolAtLocation(name);
+                        addSearch(name, defaultImportAlias);
+                    }
+                    // 'default' might be accessed as a named import `{ default as foo }`.
+                    if (!isForRename && exportKind === 1 /* Default */) {
+                        searchForNamedImport(namedBindings);
+                    }
+                }
+            }
+            /**
+             * `import x = require("./x") or `import * as x from "./x"`.
+             * An `export =` may be imported by this syntax, so it may be a direct import.
+             * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here.
+             */
+            function handleNamespaceImportLike(importName) {
+                // Don't rename an import that already has a different name than the export.
+                if (exportKind === 2 /* ExportEquals */ && (!isForRename || isNameMatch(importName.escapedText))) {
+                    addSearch(importName, checker.getSymbolAtLocation(importName));
+                }
+            }
+            function searchForNamedImport(namedBindings) {
+                if (!namedBindings) {
+                    return;
+                }
+                for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
+                    var element = _a[_i];
+                    var name = element.name, propertyName = element.propertyName;
+                    if (!isNameMatch((propertyName || name).escapedText)) {
+                        continue;
+                    }
+                    if (propertyName) {
+                        // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
+                        singleReferences.push(propertyName);
+                        if (!isForRename) {
+                            // Search locally for `bar`.
+                            addSearch(name, checker.getSymbolAtLocation(name));
+                        }
+                    }
+                    else {
+                        var localSymbol = element.kind === 246 /* ExportSpecifier */ && element.propertyName
+                            ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
+                            : checker.getSymbolAtLocation(name);
+                        addSearch(name, localSymbol);
+                    }
+                }
+            }
+            function isNameMatch(name) {
+                // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
+                return name === exportSymbol.escapedName || exportKind !== 0 /* Named */ && name === "default";
+            }
+        }
+        /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */
+        function findNamespaceReExports(sourceFileLike, name, checker) {
+            var namespaceImportSymbol = checker.getSymbolAtLocation(name);
+            return forEachPossibleImportOrExportStatement(sourceFileLike, function (statement) {
+                if (statement.kind !== 244 /* ExportDeclaration */)
+                    return;
+                var _a = statement, exportClause = _a.exportClause, moduleSpecifier = _a.moduleSpecifier;
+                if (moduleSpecifier || !exportClause)
+                    return;
+                for (var _i = 0, _b = exportClause.elements; _i < _b.length; _i++) {
+                    var element = _b[_i];
+                    if (checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol) {
+                        return true;
+                    }
+                }
+            });
+        }
+        function findModuleReferences(program, sourceFiles, searchModuleSymbol) {
+            var refs = [];
+            var checker = program.getTypeChecker();
+            for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) {
+                var referencingFile = sourceFiles_4[_i];
+                var searchSourceFile = searchModuleSymbol.valueDeclaration;
+                if (searchSourceFile.kind === 265 /* SourceFile */) {
+                    for (var _a = 0, _b = referencingFile.referencedFiles; _a < _b.length; _a++) {
+                        var ref = _b[_a];
+                        if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) {
+                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
+                        }
+                    }
+                    for (var _c = 0, _d = referencingFile.typeReferenceDirectives; _c < _d.length; _c++) {
+                        var ref = _d[_c];
+                        var referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName);
+                        if (referenced !== undefined && referenced.resolvedFileName === searchSourceFile.fileName) {
+                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
+                        }
+                    }
+                }
+                forEachImport(referencingFile, function (_importDecl, moduleSpecifier) {
+                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
+                    if (moduleSymbol === searchModuleSymbol) {
+                        refs.push({ kind: "import", literal: moduleSpecifier });
+                    }
+                });
+            }
+            return refs;
+        }
+        FindAllReferences.findModuleReferences = findModuleReferences;
+        /** Returns a map from a module symbol Id to all import statements that directly reference the module. */
+        function getDirectImportsMap(sourceFiles, checker, cancellationToken) {
+            var map = ts.createMap();
+            for (var _i = 0, sourceFiles_5 = sourceFiles; _i < sourceFiles_5.length; _i++) {
+                var sourceFile = sourceFiles_5[_i];
+                cancellationToken.throwIfCancellationRequested();
+                forEachImport(sourceFile, function (importDecl, moduleSpecifier) {
+                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
+                    if (moduleSymbol) {
+                        var id = ts.getSymbolId(moduleSymbol).toString();
+                        var imports = map.get(id);
+                        if (!imports) {
+                            map.set(id, imports = []);
+                        }
+                        imports.push(importDecl);
+                    }
+                });
+            }
+            return map;
+        }
+        /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */
+        function forEachPossibleImportOrExportStatement(sourceFileLike, action) {
+            return ts.forEach(sourceFileLike.kind === 265 /* SourceFile */ ? sourceFileLike.statements : sourceFileLike.body.statements, function (statement) {
+                return action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action));
+            });
+        }
+        /** Calls `action` for each import, re-export, or require() in a file. */
+        function forEachImport(sourceFile, action) {
+            if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) {
+                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
+                    var moduleSpecifier = _a[_i];
+                    action(importerFromModuleSpecifier(moduleSpecifier), moduleSpecifier);
+                }
+            }
+            else {
+                forEachPossibleImportOrExportStatement(sourceFile, function (statement) {
+                    switch (statement.kind) {
+                        case 244 /* ExportDeclaration */:
+                        case 238 /* ImportDeclaration */: {
+                            var decl = statement;
+                            if (decl.moduleSpecifier && decl.moduleSpecifier.kind === 9 /* StringLiteral */) {
+                                action(decl, decl.moduleSpecifier);
+                            }
+                            break;
+                        }
+                        case 237 /* ImportEqualsDeclaration */: {
+                            var decl = statement;
+                            var moduleReference = decl.moduleReference;
+                            if (moduleReference.kind === 248 /* ExternalModuleReference */ &&
+                                moduleReference.expression.kind === 9 /* StringLiteral */) {
+                                action(decl, moduleReference.expression);
+                            }
+                            break;
+                        }
+                    }
+                });
+            }
+        }
+        function importerFromModuleSpecifier(moduleSpecifier) {
+            var decl = moduleSpecifier.parent;
+            switch (decl.kind) {
+                case 181 /* CallExpression */:
+                case 238 /* ImportDeclaration */:
+                case 244 /* ExportDeclaration */:
+                    return decl;
+                case 248 /* ExternalModuleReference */:
+                    return decl.parent;
+                default:
+                    ts.Debug.fail("Unexpected module specifier parent: " + decl.kind);
+            }
+        }
+        /**
+         * Given a local reference, we might notice that it's an import/export and recursively search for references of that.
+         * If at an import, look locally for the symbol it imports.
+         * If an an export, look for all imports of it.
+         * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`.
+         * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here.
+         */
+        function getImportOrExportSymbol(node, symbol, checker, comingFromExport) {
+            return comingFromExport ? getExport() : getExport() || getImport();
+            function getExport() {
+                var parent = node.parent;
+                if (symbol.exportSymbol) {
+                    if (parent.kind === 179 /* PropertyAccessExpression */) {
+                        // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use.
+                        // So check that we are at the declaration.
+                        return symbol.declarations.some(function (d) { return d === parent; }) && ts.isBinaryExpression(parent.parent)
+                            ? getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ false)
+                            : undefined;
+                    }
+                    else {
+                        return exportInfo(symbol.exportSymbol, getExportKindForDeclaration(parent));
+                    }
+                }
+                else {
+                    var exportNode = getExportNode(parent, node);
+                    if (exportNode && ts.hasModifier(exportNode, 1 /* Export */)) {
+                        if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) {
+                            // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
+                            if (comingFromExport) {
+                                return undefined;
+                            }
+                            var lhsSymbol = checker.getSymbolAtLocation(exportNode.name);
+                            return { kind: 0 /* Import */, symbol: lhsSymbol, isNamedImport: false };
+                        }
+                        else {
+                            return exportInfo(symbol, getExportKindForDeclaration(exportNode));
+                        }
+                    }
+                    else if (ts.isExportAssignment(parent)) {
+                        return getExportAssignmentExport(parent);
+                    }
+                    else if (ts.isExportAssignment(parent.parent)) {
+                        return getExportAssignmentExport(parent.parent);
+                    }
+                    else if (ts.isBinaryExpression(parent)) {
+                        return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true);
+                    }
+                    else if (ts.isBinaryExpression(parent.parent)) {
+                        return getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ true);
+                    }
+                }
+                function getExportAssignmentExport(ex) {
+                    // Get the symbol for the `export =` node; its parent is the module it's the export of.
+                    var exportingModuleSymbol = ex.symbol.parent;
+                    ts.Debug.assert(!!exportingModuleSymbol);
+                    var exportKind = ex.isExportEquals ? 2 /* ExportEquals */ : 1 /* Default */;
+                    return { kind: 1 /* Export */, symbol: symbol, exportInfo: { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } };
+                }
+                function getSpecialPropertyExport(node, useLhsSymbol) {
+                    var kind;
+                    switch (ts.getSpecialPropertyAssignmentKind(node)) {
+                        case 1 /* ExportsProperty */:
+                            kind = 0 /* Named */;
+                            break;
+                        case 2 /* ModuleExports */:
+                            kind = 2 /* ExportEquals */;
+                            break;
+                        default:
+                            return undefined;
+                    }
+                    var sym = useLhsSymbol ? checker.getSymbolAtLocation(node.left.name) : symbol;
+                    return sym && exportInfo(sym, kind);
+                }
+            }
+            function getImport() {
+                var isImport = isNodeImport(node);
+                if (!isImport)
+                    return undefined;
+                // A symbol being imported is always an alias. So get what that aliases to find the local symbol.
+                var importedSymbol = checker.getImmediateAliasedSymbol(symbol);
+                if (!importedSymbol)
+                    return undefined;
+                // Search on the local symbol in the exporting module, not the exported symbol.
+                importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker);
+                // Similarly, skip past the symbol for 'export ='
+                if (importedSymbol.escapedName === "export=") {
+                    importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
+                }
+                // If the import has a different name than the export, do not continue searching.
+                // If `importedName` is undefined, do continue searching as the export is anonymous.
+                // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
+                var importedName = symbolName(importedSymbol);
+                if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
+                    return __assign({ kind: 0 /* Import */, symbol: importedSymbol }, isImport);
+                }
+            }
+            function exportInfo(symbol, kind) {
+                var exportInfo = getExportInfo(symbol, kind, checker);
+                return exportInfo && { kind: 1 /* Export */, symbol: symbol, exportInfo: exportInfo };
+            }
+            // Not meant for use with export specifiers or export assignment.
+            function getExportKindForDeclaration(node) {
+                return ts.hasModifier(node, 512 /* Default */) ? 1 /* Default */ : 0 /* Named */;
+            }
+        }
+        FindAllReferences.getImportOrExportSymbol = getImportOrExportSymbol;
+        function getExportEqualsLocalSymbol(importedSymbol, checker) {
+            if (importedSymbol.flags & 2097152 /* Alias */) {
+                return checker.getImmediateAliasedSymbol(importedSymbol);
+            }
+            var decl = importedSymbol.valueDeclaration;
+            if (ts.isExportAssignment(decl)) {
+                return decl.expression.symbol;
+            }
+            else if (ts.isBinaryExpression(decl)) {
+                return decl.right.symbol;
+            }
+            ts.Debug.fail();
+        }
+        // If a reference is a class expression, the exported node would be its parent.
+        // If a reference is a variable declaration, the exported node would be the variable statement.
+        function getExportNode(parent, node) {
+            if (parent.kind === 226 /* VariableDeclaration */) {
+                var p = parent;
+                return p.name !== node ? undefined :
+                    p.parent.kind === 260 /* CatchClause */ ? undefined : p.parent.parent.kind === 208 /* VariableStatement */ ? p.parent.parent : undefined;
+            }
+            else {
+                return parent;
+            }
+        }
+        function isNodeImport(node) {
+            var parent = node.parent;
+            switch (parent.kind) {
+                case 237 /* ImportEqualsDeclaration */:
+                    return parent.name === node && isExternalModuleImportEquals(parent)
+                        ? { isNamedImport: false }
+                        : undefined;
+                case 242 /* ImportSpecifier */:
+                    // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`.
+                    return parent.propertyName ? undefined : { isNamedImport: true };
+                case 239 /* ImportClause */:
+                case 240 /* NamespaceImport */:
+                    ts.Debug.assert(parent.name === node);
+                    return { isNamedImport: false };
+                default:
+                    return undefined;
+            }
+        }
+        function getExportInfo(exportSymbol, exportKind, checker) {
+            var exportingModuleSymbol = checker.getMergedSymbol(exportSymbol.parent); // Need to get merged symbol in case there's an augmentation.
+            // `export` may appear in a namespace. In that case, just rely on global search.
+            return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } : undefined;
+        }
+        FindAllReferences.getExportInfo = getExportInfo;
+        function symbolName(symbol) {
+            if (symbol.escapedName !== "default") {
+                return symbol.escapedName;
+            }
+            return ts.forEach(symbol.declarations, function (decl) {
+                var name = ts.getNameOfDeclaration(decl);
+                return name && name.kind === 71 /* Identifier */ && name.escapedText;
+            });
+        }
+        /** If at an export specifier, go to the symbol it refers to. */
+        function skipExportSpecifierSymbol(symbol, checker) {
+            // For `export { foo } from './bar", there's nothing to skip, because it does  not create a new alias. But `export { foo } does.
+            if (symbol.declarations) {
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var declaration = _a[_i];
+                    if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
+                        return checker.getExportSpecifierLocalTargetSymbol(declaration);
+                    }
+                }
+            }
+            return symbol;
+        }
+        function getContainingModuleSymbol(importer, checker) {
+            return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol);
+        }
+        function getSourceFileLikeForImportDeclaration(node) {
+            if (node.kind === 181 /* CallExpression */) {
+                return node.getSourceFile();
+            }
+            var parent = node.parent;
+            if (parent.kind === 265 /* SourceFile */) {
+                return parent;
+            }
+            ts.Debug.assert(parent.kind === 234 /* ModuleBlock */ && isAmbientModuleDeclaration(parent.parent));
+            return parent.parent;
+        }
+        function isAmbientModuleDeclaration(node) {
+            return node.kind === 233 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */;
+        }
+        function isExternalModuleImportEquals(_a) {
+            var moduleReference = _a.moduleReference;
+            return moduleReference.kind === 248 /* ExternalModuleReference */ && moduleReference.expression.kind === 9 /* StringLiteral */;
+        }
+    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
+})(ts || (ts = {}));
+/// <reference path="./importTracker.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    var FindAllReferences;
+    (function (FindAllReferences) {
+        function nodeEntry(node, isInString) {
+            return { type: "node", node: node, isInString: isInString };
+        }
+        FindAllReferences.nodeEntry = nodeEntry;
+        function findReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position) {
+            var referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
+            if (!referencedSymbols || !referencedSymbols.length) {
+                return undefined;
+            }
+            var out = [];
+            var checker = program.getTypeChecker();
+            for (var _i = 0, referencedSymbols_1 = referencedSymbols; _i < referencedSymbols_1.length; _i++) {
+                var _a = referencedSymbols_1[_i], definition = _a.definition, references = _a.references;
+                // Only include referenced symbols that have a valid definition.
+                if (definition) {
+                    out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
+                }
+            }
+            return out;
+        }
+        FindAllReferences.findReferencedSymbols = findReferencedSymbols;
+        function getImplementationsAtPosition(program, cancellationToken, sourceFiles, sourceFile, position) {
+            // A node in a JSDoc comment can't have an implementation anyway.
+            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false);
+            var referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node);
+            var checker = program.getTypeChecker();
+            return ts.map(referenceEntries, function (entry) { return toImplementationLocation(entry, checker); });
+        }
+        FindAllReferences.getImplementationsAtPosition = getImplementationsAtPosition;
+        function getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node) {
+            if (node.kind === 265 /* SourceFile */) {
+                return undefined;
+            }
+            var checker = program.getTypeChecker();
+            // If invoked directly on a shorthand property assignment, then return
+            // the declaration of the symbol being assigned (not the symbol being assigned to).
+            if (node.parent.kind === 262 /* ShorthandPropertyAssignment */) {
+                var result_5 = [];
+                FindAllReferences.Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, function (node) { return result_5.push(nodeEntry(node)); });
+                return result_5;
+            }
+            else if (node.kind === 97 /* SuperKeyword */ || ts.isSuperProperty(node.parent)) {
+                // References to and accesses on the super keyword only have one possible implementation, so no
+                // need to "Find all References"
+                var symbol = checker.getSymbolAtLocation(node);
+                return symbol.valueDeclaration && [nodeEntry(symbol.valueDeclaration)];
+            }
+            else {
+                // Perform "Find all References" and retrieve only those that are implementations
+                return getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, { implementations: true });
+            }
+        }
+        function findReferencedEntries(program, cancellationToken, sourceFiles, sourceFile, position, options) {
+            var x = flattenEntries(findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options));
+            return ts.map(x, toReferenceEntry);
+        }
+        FindAllReferences.findReferencedEntries = findReferencedEntries;
+        function getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, options) {
+            if (options === void 0) { options = {}; }
+            return flattenEntries(FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options));
+        }
+        FindAllReferences.getReferenceEntriesForNode = getReferenceEntriesForNode;
+        function findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options) {
+            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+            return FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options);
+        }
+        function flattenEntries(referenceSymbols) {
+            return referenceSymbols && ts.flatMap(referenceSymbols, function (r) { return r.references; });
+        }
+        function definitionToReferencedSymbolDefinitionInfo(def, checker) {
+            var info = (function () {
+                switch (def.type) {
+                    case "symbol": {
+                        var symbol = def.symbol, node_2 = def.node;
+                        var _a = getDefinitionKindAndDisplayParts(symbol, node_2, checker), displayParts_1 = _a.displayParts, kind_1 = _a.kind;
+                        var name_4 = displayParts_1.map(function (p) { return p.text; }).join("");
+                        return { node: node_2, name: name_4, kind: kind_1, displayParts: displayParts_1 };
+                    }
+                    case "label": {
+                        var node_3 = def.node;
+                        return { node: node_3, name: node_3.text, kind: "label" /* label */, displayParts: [ts.displayPart(node_3.text, ts.SymbolDisplayPartKind.text)] };
+                    }
+                    case "keyword": {
+                        var node_4 = def.node;
+                        var name_5 = ts.tokenToString(node_4.kind);
+                        return { node: node_4, name: name_5, kind: "keyword" /* keyword */, displayParts: [{ text: name_5, kind: "keyword" /* keyword */ }] };
+                    }
+                    case "this": {
+                        var node_5 = def.node;
+                        var symbol = checker.getSymbolAtLocation(node_5);
+                        var displayParts_2 = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node_5.getSourceFile(), ts.getContainerNode(node_5), node_5).displayParts;
+                        return { node: node_5, name: "this", kind: "var" /* variableElement */, displayParts: displayParts_2 };
+                    }
+                    case "string": {
+                        var node_6 = def.node;
+                        return { node: node_6, name: node_6.text, kind: "var" /* variableElement */, displayParts: [ts.displayPart(ts.getTextOfNode(node_6), ts.SymbolDisplayPartKind.stringLiteral)] };
+                    }
+                }
+            })();
+            if (!info) {
+                return undefined;
+            }
+            var node = info.node, name = info.name, kind = info.kind, displayParts = info.displayParts;
+            var sourceFile = node.getSourceFile();
+            return {
+                containerKind: "" /* unknown */,
+                containerName: "",
+                fileName: sourceFile.fileName,
+                kind: kind,
+                name: name,
+                textSpan: ts.createTextSpanFromNode(node, sourceFile),
+                displayParts: displayParts
+            };
+        }
+        function getDefinitionKindAndDisplayParts(symbol, node, checker) {
+            var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node.getSourceFile(), ts.getContainerNode(node), node), displayParts = _a.displayParts, symbolKind = _a.symbolKind;
+            return { displayParts: displayParts, kind: symbolKind };
+        }
+        function toReferenceEntry(entry) {
+            if (entry.type === "span") {
+                return { textSpan: entry.textSpan, fileName: entry.fileName, isWriteAccess: false, isDefinition: false };
+            }
+            var node = entry.node, isInString = entry.isInString;
+            return {
+                fileName: node.getSourceFile().fileName,
+                textSpan: getTextSpan(node),
+                isWriteAccess: isWriteAccessForReference(node),
+                isDefinition: node.kind === 79 /* DefaultKeyword */
+                    || ts.isAnyDeclarationName(node)
+                    || ts.isLiteralComputedPropertyDeclarationName(node),
+                isInString: isInString
+            };
+        }
+        function toImplementationLocation(entry, checker) {
+            if (entry.type === "node") {
+                var node = entry.node;
+                return __assign({ textSpan: getTextSpan(node), fileName: node.getSourceFile().fileName }, implementationKindDisplayParts(node, checker));
+            }
+            else {
+                var textSpan = entry.textSpan, fileName = entry.fileName;
+                return { textSpan: textSpan, fileName: fileName, kind: "" /* unknown */, displayParts: [] };
+            }
+        }
+        function implementationKindDisplayParts(node, checker) {
+            var symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node);
+            if (symbol) {
+                return getDefinitionKindAndDisplayParts(symbol, node, checker);
+            }
+            else if (node.kind === 178 /* ObjectLiteralExpression */) {
+                return {
+                    kind: "interface" /* interfaceElement */,
+                    displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("object literal"), ts.punctuationPart(20 /* CloseParenToken */)]
+                };
+            }
+            else if (node.kind === 199 /* ClassExpression */) {
+                return {
+                    kind: "local class" /* localClassElement */,
+                    displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("anonymous local class"), ts.punctuationPart(20 /* CloseParenToken */)]
+                };
+            }
+            else {
+                return { kind: ts.getNodeKind(node), displayParts: [] };
+            }
+        }
+        function toHighlightSpan(entry) {
+            if (entry.type === "span") {
+                var fileName_1 = entry.fileName, textSpan = entry.textSpan;
+                return { fileName: fileName_1, span: { textSpan: textSpan, kind: "reference" /* reference */ } };
+            }
+            var node = entry.node, isInString = entry.isInString;
+            var fileName = entry.node.getSourceFile().fileName;
+            var writeAccess = isWriteAccessForReference(node);
+            var span = {
+                textSpan: getTextSpan(node),
+                kind: writeAccess ? "writtenReference" /* writtenReference */ : "reference" /* reference */,
+                isInString: isInString
+            };
+            return { fileName: fileName, span: span };
+        }
+        FindAllReferences.toHighlightSpan = toHighlightSpan;
+        function getTextSpan(node) {
+            var start = node.getStart();
+            var end = node.getEnd();
+            if (node.kind === 9 /* StringLiteral */) {
+                start += 1;
+                end -= 1;
+            }
+            return ts.createTextSpanFromBounds(start, end);
+        }
+        /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
+        function isWriteAccessForReference(node) {
+            return node.kind === 79 /* DefaultKeyword */ || ts.isAnyDeclarationName(node) || ts.isWriteAccess(node);
+        }
+    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
+})(ts || (ts = {}));
+/** Encapsulates the core find-all-references algorithm. */
+/* @internal */
+(function (ts) {
+    var FindAllReferences;
+    (function (FindAllReferences) {
+        var Core;
+        (function (Core) {
+            /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */
+            function getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options) {
+                if (options === void 0) { options = {}; }
+                if (node.kind === 265 /* SourceFile */) {
+                    return undefined;
+                }
+                if (!options.implementations) {
+                    var special = getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken);
+                    if (special) {
+                        return special;
+                    }
+                }
+                var checker = program.getTypeChecker();
+                var symbol = checker.getSymbolAtLocation(node);
+                // Could not find a symbol e.g. unknown identifier
+                if (!symbol) {
+                    // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial.
+                    if (!options.implementations && node.kind === 9 /* StringLiteral */) {
+                        return getReferencesForStringLiteral(node, sourceFiles, cancellationToken);
+                    }
+                    // Can't have references to something that we have no symbol for.
+                    return undefined;
+                }
+                if (symbol.flags & 1536 /* Module */ && isModuleReferenceLocation(node)) {
+                    return getReferencedSymbolsForModule(program, symbol, sourceFiles);
+                }
+                return getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options);
+            }
+            Core.getReferencedSymbolsForNode = getReferencedSymbolsForNode;
+            function isModuleReferenceLocation(node) {
+                if (node.kind !== 9 /* StringLiteral */) {
+                    return false;
+                }
+                switch (node.parent.kind) {
+                    case 233 /* ModuleDeclaration */:
+                    case 248 /* ExternalModuleReference */:
+                    case 238 /* ImportDeclaration */:
+                    case 244 /* ExportDeclaration */:
+                        return true;
+                    case 181 /* CallExpression */:
+                        return ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || ts.isImportCall(node.parent);
+                    default:
+                        return false;
+                }
+            }
+            function getReferencedSymbolsForModule(program, symbol, sourceFiles) {
+                ts.Debug.assert(!!symbol.valueDeclaration);
+                var references = FindAllReferences.findModuleReferences(program, sourceFiles, symbol).map(function (reference) {
+                    if (reference.kind === "import") {
+                        return { type: "node", node: reference.literal };
+                    }
+                    else {
+                        return {
+                            type: "span",
+                            fileName: reference.referencingFile.fileName,
+                            textSpan: ts.createTextSpanFromRange(reference.ref),
+                        };
+                    }
+                });
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    switch (decl.kind) {
+                        case 265 /* SourceFile */:
+                            // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.)
+                            break;
+                        case 233 /* ModuleDeclaration */:
+                            references.push({ type: "node", node: decl.name });
+                            break;
+                        default:
+                            ts.Debug.fail("Expected a module symbol to be declared by a SourceFile or ModuleDeclaration.");
+                    }
+                }
+                return [{
+                        definition: { type: "symbol", symbol: symbol, node: symbol.valueDeclaration },
+                        references: references
+                    }];
+            }
+            /** getReferencedSymbols for special node kinds. */
+            function getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken) {
+                if (ts.isTypeKeyword(node.kind)) {
+                    return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken);
+                }
+                // Labels
+                if (ts.isLabelName(node)) {
+                    if (ts.isJumpStatementTarget(node)) {
+                        var labelDefinition = ts.getTargetLabel(node.parent, node.text);
+                        // if we have a label definition, look within its statement for references, if not, then
+                        // the label is undefined and we have no results..
+                        return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
+                    }
+                    else {
+                        // it is a label definition and not a target, search within the parent labeledStatement
+                        return getLabelReferencesInNode(node.parent, node);
+                    }
+                }
+                if (ts.isThis(node)) {
+                    return getReferencesForThisKeyword(node, sourceFiles, cancellationToken);
+                }
+                if (node.kind === 97 /* SuperKeyword */) {
+                    return getReferencesForSuperKeyword(node);
+                }
+                return undefined;
+            }
+            /** Core find-all-references algorithm for a normal symbol. */
+            function getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options) {
+                symbol = skipPastExportOrImportSpecifier(symbol, node, checker);
+                // Compute the meaning from the location and the symbol it references
+                var searchMeaning = getIntersectingMeaningFromDeclarations(ts.getMeaningFromLocation(node), symbol.declarations);
+                var result = [];
+                var state = new State(sourceFiles, /*isForConstructor*/ node.kind === 123 /* ConstructorKeyword */, checker, cancellationToken, searchMeaning, options, result);
+                if (node.kind === 79 /* DefaultKeyword */) {
+                    addReference(node, symbol, node, state);
+                    searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: 1 /* Default */ }, state);
+                }
+                else {
+                    var search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) });
+                    // Try to get the smallest valid scope that we can limit our search to;
+                    // otherwise we'll need to search globally (i.e. include each file).
+                    var scope = getSymbolScope(symbol);
+                    if (scope) {
+                        getReferencesInContainer(scope, scope.getSourceFile(), search, state);
+                    }
+                    else {
+                        // Global search
+                        for (var _i = 0, _a = state.sourceFiles; _i < _a.length; _i++) {
+                            var sourceFile = _a[_i];
+                            state.cancellationToken.throwIfCancellationRequested();
+                            searchForName(sourceFile, search, state);
+                        }
+                    }
+                }
+                return result;
+            }
+            /** Handle a few special cases relating to export/import specifiers. */
+            function skipPastExportOrImportSpecifier(symbol, node, checker) {
+                var parent = node.parent;
+                if (ts.isExportSpecifier(parent)) {
+                    return getLocalSymbolForExportSpecifier(node, symbol, parent, checker);
+                }
+                if (ts.isImportSpecifier(parent) && parent.propertyName === node) {
+                    // We're at `foo` in `import { foo as bar }`. Probably intended to find all refs on the original, not just on the import.
+                    return checker.getImmediateAliasedSymbol(symbol);
+                }
+                return symbol;
+            }
+            /**
+             * Holds all state needed for the finding references.
+             * Unlike `Search`, there is only one `State`.
+             */
+            var State = /** @class */ (function () {
+                function State(sourceFiles, 
+                    /** True if we're searching for constructor references. */
+                    isForConstructor, checker, cancellationToken, searchMeaning, options, result) {
+                    this.sourceFiles = sourceFiles;
+                    this.isForConstructor = isForConstructor;
+                    this.checker = checker;
+                    this.cancellationToken = cancellationToken;
+                    this.searchMeaning = searchMeaning;
+                    this.options = options;
+                    this.result = result;
+                    /** Cache for `explicitlyinheritsFrom`. */
+                    this.inheritsFromCache = ts.createMap();
+                    /**
+                     * Type nodes can contain multiple references to the same type. For example:
+                     *      let x: Foo & (Foo & Bar) = ...
+                     * Because we are returning the implementation locations and not the identifier locations,
+                     * duplicate entries would be returned here as each of the type references is part of
+                     * the same implementation. For that reason, check before we add a new entry.
+                     */
+                    this.markSeenContainingTypeReference = ts.nodeSeenTracker();
+                    /**
+                     * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
+                     * For example:
+                     *     // b.ts
+                     *     export { foo as bar } from "./a";
+                     *     import { bar } from "./b";
+                     *
+                     * Normally at `foo as bar` we directly add `foo` and do not locally search for it (since it doesn't declare a local).
+                     * But another reference to it may appear in the same source file.
+                     * See `tests/cases/fourslash/transitiveExportImports3.ts`.
+                     */
+                    this.markSeenReExportRHS = ts.nodeSeenTracker();
+                    this.symbolIdToReferences = [];
+                    // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
+                    this.sourceFileToSeenSymbols = [];
+                }
+                /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
+                State.prototype.getImportSearches = function (exportSymbol, exportInfo) {
+                    if (!this.importTracker)
+                        this.importTracker = FindAllReferences.createImportTracker(this.sourceFiles, this.checker, this.cancellationToken);
+                    return this.importTracker(exportSymbol, exportInfo, this.options.isForRename);
+                };
+                /** @param allSearchSymbols set of additinal symbols for use by `includes`. */
+                State.prototype.createSearch = function (location, symbol, comingFrom, searchOptions) {
+                    if (searchOptions === void 0) { searchOptions = {}; }
+                    // Note: if this is an external module symbol, the name doesn't include quotes.
+                    var _a = searchOptions.text, text = _a === void 0 ? ts.stripQuotes(ts.unescapeLeadingUnderscores((ts.getLocalSymbolForExportDefault(symbol) || symbol).escapedName)) : _a, _b = searchOptions.allSearchSymbols, allSearchSymbols = _b === void 0 ? undefined : _b;
+                    var escapedText = ts.escapeLeadingUnderscores(text);
+                    var parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
+                    return {
+                        location: location, symbol: symbol, comingFrom: comingFrom, text: text, escapedText: escapedText, parents: parents,
+                        includes: function (referenceSymbol) { return allSearchSymbols ? ts.contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol; },
+                    };
+                };
+                /**
+                 * Callback to add references for a particular searched symbol.
+                 * This initializes a reference group, so only call this if you will add at least one reference.
+                 */
+                State.prototype.referenceAdder = function (searchSymbol, searchLocation) {
+                    var symbolId = ts.getSymbolId(searchSymbol);
+                    var references = this.symbolIdToReferences[symbolId];
+                    if (!references) {
+                        references = this.symbolIdToReferences[symbolId] = [];
+                        this.result.push({ definition: { type: "symbol", symbol: searchSymbol, node: searchLocation }, references: references });
+                    }
+                    return function (node) { return references.push(FindAllReferences.nodeEntry(node)); };
+                };
+                /** Add a reference with no associated definition. */
+                State.prototype.addStringOrCommentReference = function (fileName, textSpan) {
+                    this.result.push({
+                        definition: undefined,
+                        references: [{ type: "span", fileName: fileName, textSpan: textSpan }]
+                    });
+                };
+                /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
+                State.prototype.markSearchedSymbol = function (sourceFile, symbol) {
+                    var sourceId = ts.getNodeId(sourceFile);
+                    var symbolId = ts.getSymbolId(symbol);
+                    var seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []);
+                    return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true);
+                };
+                return State;
+            }());
+            /** Search for all imports of a given exported symbol using `State.getImportSearches`. */
+            function searchForImportsOfExport(exportLocation, exportSymbol, exportInfo, state) {
+                var _a = state.getImportSearches(exportSymbol, exportInfo), importSearches = _a.importSearches, singleReferences = _a.singleReferences, indirectUsers = _a.indirectUsers;
+                // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file.
+                if (singleReferences.length) {
+                    var addRef = state.referenceAdder(exportSymbol, exportLocation);
+                    for (var _i = 0, singleReferences_1 = singleReferences; _i < singleReferences_1.length; _i++) {
+                        var singleRef = singleReferences_1[_i];
+                        addRef(singleRef);
+                    }
+                }
+                // For each import, find all references to that import in its source file.
+                for (var _b = 0, importSearches_1 = importSearches; _b < importSearches_1.length; _b++) {
+                    var _c = importSearches_1[_b], importLocation = _c[0], importSymbol = _c[1];
+                    getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, 1 /* Export */), state);
+                }
+                if (indirectUsers.length) {
+                    var indirectSearch = void 0;
+                    switch (exportInfo.exportKind) {
+                        case 0 /* Named */:
+                            indirectSearch = state.createSearch(exportLocation, exportSymbol, 1 /* Export */);
+                            break;
+                        case 1 /* Default */:
+                            // Search for a property access to '.default'. This can't be renamed.
+                            indirectSearch = state.options.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, 1 /* Export */, { text: "default" });
+                            break;
+                        case 2 /* ExportEquals */:
+                            break;
+                    }
+                    if (indirectSearch) {
+                        for (var _d = 0, indirectUsers_1 = indirectUsers; _d < indirectUsers_1.length; _d++) {
+                            var indirectUser = indirectUsers_1[_d];
+                            searchForName(indirectUser, indirectSearch, state);
+                        }
+                    }
+                }
+            }
+            // Go to the symbol we imported from and find references for it.
+            function searchForImportedSymbol(symbol, state) {
+                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                    var declaration = _a[_i];
+                    getReferencesInSourceFile(declaration.getSourceFile(), state.createSearch(declaration, symbol, 0 /* Import */), state);
+                }
+            }
+            /** Search for all occurences of an identifier in a source file (and filter out the ones that match). */
+            function searchForName(sourceFile, search, state) {
+                if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) {
+                    getReferencesInSourceFile(sourceFile, search, state);
+                }
+            }
+            function getPropertySymbolOfDestructuringAssignment(location, checker) {
+                return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) &&
+                    checker.getPropertySymbolOfDestructuringAssignment(location);
+            }
+            function getObjectBindingElementWithoutPropertyName(symbol) {
+                var bindingElement = ts.getDeclarationOfKind(symbol, 176 /* BindingElement */);
+                if (bindingElement &&
+                    bindingElement.parent.kind === 174 /* ObjectBindingPattern */ &&
+                    !bindingElement.propertyName) {
+                    return bindingElement;
+                }
+            }
+            function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) {
+                var bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
+                if (!bindingElement)
+                    return undefined;
+                var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
+                var propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
+                if (propSymbol && propSymbol.flags & 98304 /* Accessor */) {
+                    // See GH#16922
+                    ts.Debug.assert(!!(propSymbol.flags & 33554432 /* Transient */));
+                    return propSymbol.target;
+                }
+                return propSymbol;
+            }
+            /**
+             * Determines the smallest scope in which a symbol may have named references.
+             * Note that not every construct has been accounted for. This function can
+             * probably be improved.
+             *
+             * @returns undefined if the scope cannot be determined, implying that
+             * a reference to a symbol can occur anywhere.
+             */
+            function getSymbolScope(symbol) {
+                // If this is the symbol of a named function expression or named class expression,
+                // then named references are limited to its own scope.
+                var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration;
+                if (valueDeclaration && (valueDeclaration.kind === 186 /* FunctionExpression */ || valueDeclaration.kind === 199 /* ClassExpression */)) {
+                    return valueDeclaration;
+                }
+                if (!declarations) {
+                    return undefined;
+                }
+                // If this is private property or method, the scope is the containing class
+                if (flags & (4 /* Property */ | 8192 /* Method */)) {
+                    var privateDeclaration = ts.find(declarations, function (d) { return ts.hasModifier(d, 8 /* Private */); });
+                    if (privateDeclaration) {
+                        return ts.getAncestor(privateDeclaration, 229 /* ClassDeclaration */);
+                    }
+                    // Else this is a public property and could be accessed from anywhere.
+                    return undefined;
+                }
+                // If symbol is of object binding pattern element without property name we would want to
+                // look for property too and that could be anywhere
+                if (getObjectBindingElementWithoutPropertyName(symbol)) {
+                    return undefined;
+                }
+                /*
+                If the symbol has a parent, it's globally visible unless:
+                - It's a private property (handled above).
+                - It's a type parameter.
+                - The parent is an external module: then we should only search in the module (and recurse on the export later).
+                  - But if the parent has `export as namespace`, the symbol is globally visible through that namespace.
+                */
+                var exposedByParent = parent && !(symbol.flags & 262144 /* TypeParameter */);
+                if (exposedByParent && !((parent.flags & 1536 /* Module */) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) {
+                    return undefined;
+                }
+                var scope;
+                for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
+                    var declaration = declarations_9[_i];
+                    var container = ts.getContainerNode(declaration);
+                    if (scope && scope !== container) {
+                        // Different declarations have different containers, bail out
+                        return undefined;
+                    }
+                    if (!container || container.kind === 265 /* SourceFile */ && !ts.isExternalOrCommonJsModule(container)) {
+                        // This is a global variable and not an external module, any declaration defined
+                        // within this scope is visible outside the file
+                        return undefined;
+                    }
+                    // The search scope is the container node
+                    scope = container;
+                }
+                // If symbol.parent, this means we are in an export of an external module. (Otherwise we would have returned `undefined` above.)
+                // For an export of a module, we may be in a declaration file, and it may be accessed elsewhere. E.g.:
+                //     declare module "a" { export type T = number; }
+                //     declare module "b" { import { T } from "a"; export const x: T; }
+                // So we must search the whole source file. (Because we will mark the source file as seen, we we won't return to it when searching for imports.)
+                return exposedByParent ? scope.getSourceFile() : scope;
+            }
+            function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) {
+                if (container === void 0) { container = sourceFile; }
+                var positions = [];
+                /// TODO: Cache symbol existence for files to save text search
+                // Also, need to make this work for unicode escapes.
+                // Be resilient in the face of a symbol with no name or zero length name
+                if (!symbolName || !symbolName.length) {
+                    return positions;
+                }
+                var text = sourceFile.text;
+                var sourceLength = text.length;
+                var symbolNameLength = symbolName.length;
+                var position = text.indexOf(symbolName, container.pos);
+                while (position >= 0) {
+                    // If we are past the end, stop looking
+                    if (position > container.end)
+                        break;
+                    // We found a match.  Make sure it's not part of a larger word (i.e. the char
+                    // before and after it have to be a non-identifier char).
+                    var endPosition = position + symbolNameLength;
+                    if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 5 /* Latest */)) &&
+                        (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 5 /* Latest */))) {
+                        // Found a real match.  Keep searching.
+                        positions.push(position);
+                    }
+                    position = text.indexOf(symbolName, position + symbolNameLength + 1);
+                }
+                return positions;
+            }
+            function getLabelReferencesInNode(container, targetLabel) {
+                var references = [];
+                var sourceFile = container.getSourceFile();
+                var labelName = targetLabel.text;
+                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
+                for (var _i = 0, possiblePositions_1 = possiblePositions; _i < possiblePositions_1.length; _i++) {
+                    var position = possiblePositions_1[_i];
+                    var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
+                    // Only pick labels that are either the target label, or have a target that is the target label
+                    if (node && (node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel))) {
+                        references.push(FindAllReferences.nodeEntry(node));
+                    }
+                }
+                return [{ definition: { type: "label", node: targetLabel }, references: references }];
+            }
+            function isValidReferencePosition(node, searchSymbolName) {
+                // Compare the length so we filter out strict superstrings of the symbol we are looking for
+                switch (node.kind) {
+                    case 71 /* Identifier */:
+                        return node.text.length === searchSymbolName.length;
+                    case 9 /* StringLiteral */:
+                        return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
+                            node.text.length === searchSymbolName.length;
+                    case 8 /* NumericLiteral */:
+                        return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.text.length === searchSymbolName.length;
+                    case 79 /* DefaultKeyword */:
+                        return "default".length === searchSymbolName.length;
+                    default:
+                        return false;
+                }
+            }
+            function getAllReferencesForKeyword(sourceFiles, keywordKind, cancellationToken) {
+                var references = [];
+                for (var _i = 0, sourceFiles_6 = sourceFiles; _i < sourceFiles_6.length; _i++) {
+                    var sourceFile = sourceFiles_6[_i];
+                    cancellationToken.throwIfCancellationRequested();
+                    addReferencesForKeywordInFile(sourceFile, keywordKind, ts.tokenToString(keywordKind), references);
+                }
+                return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references: references }] : undefined;
+            }
+            function addReferencesForKeywordInFile(sourceFile, kind, searchText, references) {
+                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile);
+                for (var _i = 0, possiblePositions_2 = possiblePositions; _i < possiblePositions_2.length; _i++) {
+                    var position = possiblePositions_2[_i];
+                    var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+                    if (referenceLocation.kind === kind) {
+                        references.push(FindAllReferences.nodeEntry(referenceLocation));
+                    }
+                }
+            }
+            function getReferencesInSourceFile(sourceFile, search, state) {
+                state.cancellationToken.throwIfCancellationRequested();
+                return getReferencesInContainer(sourceFile, sourceFile, search, state);
+            }
+            /**
+             * Search within node "container" for references for a search value, where the search value is defined as a
+             * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
+             * searchLocation: a node where the search value
+             */
+            function getReferencesInContainer(container, sourceFile, search, state) {
+                if (!state.markSearchedSymbol(sourceFile, search.symbol)) {
+                    return;
+                }
+                for (var _i = 0, _a = getPossibleSymbolReferencePositions(sourceFile, search.text, container); _i < _a.length; _i++) {
+                    var position = _a[_i];
+                    getReferencesAtLocation(sourceFile, position, search, state);
+                }
+            }
+            function getReferencesAtLocation(sourceFile, position, search, state) {
+                var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+                if (!isValidReferencePosition(referenceLocation, search.text)) {
+                    // This wasn't the start of a token.  Check to see if it might be a
+                    // match in a comment or string if that's what the caller is asking
+                    // for.
+                    if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) {
+                        // In the case where we're looking inside comments/strings, we don't have
+                        // an actual definition.  So just use 'undefined' here.  Features like
+                        // 'Rename' won't care (as they ignore the definitions), and features like
+                        // 'FindReferences' will just filter out these results.
+                        state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length));
+                    }
+                    return;
+                }
+                if (!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning)) {
+                    return;
+                }
+                var referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation);
+                if (!referenceSymbol) {
+                    return;
+                }
+                var parent = referenceLocation.parent;
+                if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) {
+                    // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again.
+                    return;
+                }
+                if (ts.isExportSpecifier(parent)) {
+                    ts.Debug.assert(referenceLocation.kind === 71 /* Identifier */);
+                    getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, parent, search, state);
+                    return;
+                }
+                var relatedSymbol = getRelatedSymbol(search, referenceSymbol, referenceLocation, state);
+                if (!relatedSymbol) {
+                    getReferenceForShorthandProperty(referenceSymbol, search, state);
+                    return;
+                }
+                if (state.isForConstructor) {
+                    findConstructorReferences(referenceLocation, sourceFile, search, state);
+                }
+                else {
+                    addReference(referenceLocation, relatedSymbol, search.location, state);
+                }
+                getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
+            }
+            function getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, search, state) {
+                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
+                var exportDeclaration = parent.parent;
+                var localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker);
+                if (!search.includes(localSymbol)) {
+                    return;
+                }
+                if (!propertyName) {
+                    addRef();
+                }
+                else if (referenceLocation === propertyName) {
+                    // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export.
+                    // For `export { foo as bar };`, where `foo` is a local, so add it now.
+                    if (!exportDeclaration.moduleSpecifier) {
+                        addRef();
+                    }
+                    if (!state.options.isForRename && state.markSeenReExportRHS(name)) {
+                        addReference(name, referenceSymbol, name, state);
+                    }
+                }
+                else {
+                    if (state.markSeenReExportRHS(referenceLocation)) {
+                        addRef();
+                    }
+                }
+                // For `export { foo as bar }`, rename `foo`, but not `bar`.
+                if (!(referenceLocation === propertyName && state.options.isForRename)) {
+                    var exportKind = referenceLocation.originalKeywordKind === 79 /* DefaultKeyword */ ? 1 /* Default */ : 0 /* Named */;
+                    var exportInfo = FindAllReferences.getExportInfo(referenceSymbol, exportKind, state.checker);
+                    ts.Debug.assert(!!exportInfo);
+                    searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state);
+                }
+                // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`.
+                if (search.comingFrom !== 1 /* Export */ && exportDeclaration.moduleSpecifier && !propertyName) {
+                    searchForImportedSymbol(state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier), state);
+                }
+                function addRef() {
+                    addReference(referenceLocation, localSymbol, search.location, state);
+                }
+            }
+            function getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, checker) {
+                return isExportSpecifierAlias(referenceLocation, exportSpecifier) ? checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) : referenceSymbol;
+            }
+            function isExportSpecifierAlias(referenceLocation, exportSpecifier) {
+                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
+                ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation);
+                if (propertyName) {
+                    // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol.
+                    return propertyName === referenceLocation;
+                }
+                else {
+                    // `export { foo } from "foo"` is a re-export.
+                    // `export { foo };` is not a re-export, it creates an alias for the local variable `foo`.
+                    return !parent.parent.moduleSpecifier;
+                }
+            }
+            function getImportOrExportReferences(referenceLocation, referenceSymbol, search, state) {
+                var importOrExport = FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === 1 /* Export */);
+                if (!importOrExport)
+                    return;
+                var symbol = importOrExport.symbol;
+                if (importOrExport.kind === 0 /* Import */) {
+                    if (!state.options.isForRename || importOrExport.isNamedImport) {
+                        searchForImportedSymbol(symbol, state);
+                    }
+                }
+                else {
+                    // We don't check for `state.isForRename`, even for default exports, because importers that previously matched the export name should be updated to continue matching.
+                    searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state);
+                }
+            }
+            function getReferenceForShorthandProperty(_a, search, state) {
+                var flags = _a.flags, valueDeclaration = _a.valueDeclaration;
+                var shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration);
+                /*
+                 * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment
+                 * has two meanings: property name and property value. Therefore when we do findAllReference at the position where
+                 * an identifier is declared, the language service should return the position of the variable declaration as well as
+                 * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the
+                 * position of property accessing, the referenceEntry of such position will be handled in the first case.
+                 */
+                if (!(flags & 33554432 /* Transient */) && search.includes(shorthandValueSymbol)) {
+                    addReference(ts.getNameOfDeclaration(valueDeclaration), shorthandValueSymbol, search.location, state);
+                }
+            }
+            function addReference(referenceLocation, relatedSymbol, searchLocation, state) {
+                var addRef = state.referenceAdder(relatedSymbol, searchLocation);
+                if (state.options.implementations) {
+                    addImplementationReferences(referenceLocation, addRef, state);
+                }
+                else {
+                    addRef(referenceLocation);
+                }
+            }
+            /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses.  */
+            function findConstructorReferences(referenceLocation, sourceFile, search, state) {
+                if (ts.isNewExpressionTarget(referenceLocation)) {
+                    addReference(referenceLocation, search.symbol, search.location, state);
+                }
+                var pusher = state.referenceAdder(search.symbol, search.location);
+                if (ts.isClassLike(referenceLocation.parent)) {
+                    ts.Debug.assert(referenceLocation.parent.name === referenceLocation);
+                    // This is the class declaration containing the constructor.
+                    findOwnConstructorReferences(search.symbol, sourceFile, pusher);
+                }
+                else {
+                    // If this class appears in `extends C`, then the extending class' "super" calls are references.
+                    var classExtending = tryGetClassByExtendingIdentifier(referenceLocation);
+                    if (classExtending && ts.isClassLike(classExtending)) {
+                        findSuperConstructorAccesses(classExtending, pusher);
+                    }
+                }
+            }
+            function getPropertyAccessExpressionFromRightHandSide(node) {
+                return ts.isRightSideOfPropertyAccess(node) && node.parent;
+            }
+            /**
+             * `classSymbol` is the class where the constructor was defined.
+             * Reference the constructor and all calls to `new this()`.
+             */
+            function findOwnConstructorReferences(classSymbol, sourceFile, addNode) {
+                for (var _i = 0, _a = classSymbol.members.get("__constructor" /* Constructor */).declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    var ctrKeyword = ts.findChildOfKind(decl, 123 /* ConstructorKeyword */, sourceFile);
+                    ts.Debug.assert(decl.kind === 152 /* Constructor */ && !!ctrKeyword);
+                    addNode(ctrKeyword);
+                }
+                classSymbol.exports.forEach(function (member) {
+                    var decl = member.valueDeclaration;
+                    if (decl && decl.kind === 151 /* MethodDeclaration */) {
+                        var body = decl.body;
+                        if (body) {
+                            forEachDescendantOfKind(body, 99 /* ThisKeyword */, function (thisKeyword) {
+                                if (ts.isNewExpressionTarget(thisKeyword)) {
+                                    addNode(thisKeyword);
+                                }
+                            });
+                        }
+                    }
+                });
+            }
+            /** Find references to `super` in the constructor of an extending class.  */
+            function findSuperConstructorAccesses(cls, addNode) {
+                var symbol = cls.symbol;
+                var ctr = symbol.members.get("__constructor" /* Constructor */);
+                if (!ctr) {
+                    return;
+                }
+                for (var _i = 0, _a = ctr.declarations; _i < _a.length; _i++) {
+                    var decl = _a[_i];
+                    ts.Debug.assert(decl.kind === 152 /* Constructor */);
+                    var body = decl.body;
+                    if (body) {
+                        forEachDescendantOfKind(body, 97 /* SuperKeyword */, function (node) {
+                            if (ts.isCallExpressionTarget(node)) {
+                                addNode(node);
+                            }
+                        });
+                    }
+                }
+            }
+            function addImplementationReferences(refNode, addReference, state) {
+                // Check if we found a function/propertyAssignment/method with an implementation or initializer
+                if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) {
+                    addReference(refNode.parent);
+                    return;
+                }
+                if (refNode.kind !== 71 /* Identifier */) {
+                    return;
+                }
+                if (refNode.parent.kind === 262 /* ShorthandPropertyAssignment */) {
+                    // Go ahead and dereference the shorthand assignment by going to its definition
+                    getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference);
+                }
+                // Check if the node is within an extends or implements clause
+                var containingClass = getContainingClassIfInHeritageClause(refNode);
+                if (containingClass) {
+                    addReference(containingClass);
+                    return;
+                }
+                // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
+                var containingTypeReference = getContainingTypeReference(refNode);
+                if (containingTypeReference && state.markSeenContainingTypeReference(containingTypeReference)) {
+                    var parent = containingTypeReference.parent;
+                    if (ts.isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) {
+                        addReference(parent.initializer);
+                    }
+                    else if (ts.isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) {
+                        var body = parent.body;
+                        if (body.kind === 207 /* Block */) {
+                            ts.forEachReturnStatement(body, function (returnStatement) {
+                                if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) {
+                                    addReference(returnStatement.expression);
+                                }
+                            });
+                        }
+                        else if (isImplementationExpression(body)) {
+                            addReference(body);
+                        }
+                    }
+                    else if (ts.isAssertionExpression(parent) && isImplementationExpression(parent.expression)) {
+                        addReference(parent.expression);
+                    }
+                }
+            }
+            function getSymbolsForClassAndInterfaceComponents(type, result) {
+                if (result === void 0) { result = []; }
+                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
+                    var componentType = _a[_i];
+                    if (componentType.symbol && componentType.symbol.getFlags() & (32 /* Class */ | 64 /* Interface */)) {
+                        result.push(componentType.symbol);
+                    }
+                    if (componentType.getFlags() & 196608 /* UnionOrIntersection */) {
+                        getSymbolsForClassAndInterfaceComponents(componentType, result);
+                    }
+                }
+                return result;
+            }
+            function getContainingTypeReference(node) {
+                var topLevelTypeReference = undefined;
+                while (node) {
+                    if (ts.isTypeNode(node)) {
+                        topLevelTypeReference = node;
+                    }
+                    node = node.parent;
+                }
+                return topLevelTypeReference;
+            }
+            function getContainingClassIfInHeritageClause(node) {
+                if (node && node.parent) {
+                    if (node.kind === 201 /* ExpressionWithTypeArguments */
+                        && node.parent.kind === 259 /* HeritageClause */
+                        && ts.isClassLike(node.parent.parent)) {
+                        return node.parent.parent;
+                    }
+                    else if (node.kind === 71 /* Identifier */ || node.kind === 179 /* PropertyAccessExpression */) {
+                        return getContainingClassIfInHeritageClause(node.parent);
+                    }
+                }
+                return undefined;
+            }
+            /**
+             * Returns true if this is an expression that can be considered an implementation
+             */
+            function isImplementationExpression(node) {
+                switch (node.kind) {
+                    case 185 /* ParenthesizedExpression */:
+                        return isImplementationExpression(node.expression);
+                    case 187 /* ArrowFunction */:
+                    case 186 /* FunctionExpression */:
+                    case 178 /* ObjectLiteralExpression */:
+                    case 199 /* ClassExpression */:
+                    case 177 /* ArrayLiteralExpression */:
+                        return true;
+                    default:
+                        return false;
+                }
+            }
+            /**
+             * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol
+             * is an interface, determines if some ancestor of the child symbol extends or inherits from it.
+             * Also takes in a cache of previous results which makes this slightly more efficient and is
+             * necessary to avoid potential loops like so:
+             *     class A extends B { }
+             *     class B extends A { }
+             *
+             * We traverse the AST rather than using the type checker because users are typically only interested
+             * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling
+             * implementations of types that share a common ancestor with the type whose implementation we are
+             * searching for need to be filtered out of the results. The type checker doesn't let us make the
+             * distinction between structurally compatible implementations and explicit implementations, so we
+             * must use the AST.
+             *
+             * @param child         A class or interface Symbol
+             * @param parent        Another class or interface Symbol
+             * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results
+             */
+            function explicitlyInheritsFrom(child, parent, cachedResults, checker) {
+                var parentIsInterface = parent.getFlags() & 64 /* Interface */;
+                return searchHierarchy(child);
+                function searchHierarchy(symbol) {
+                    if (symbol === parent) {
+                        return true;
+                    }
+                    var key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent);
+                    var cached = cachedResults.get(key);
+                    if (cached !== undefined) {
+                        return cached;
+                    }
+                    // Set the key so that we don't infinitely recurse
+                    cachedResults.set(key, false);
+                    var inherits = ts.forEach(symbol.getDeclarations(), function (declaration) {
+                        if (ts.isClassLike(declaration)) {
+                            if (parentIsInterface) {
+                                var interfaceReferences = ts.getClassImplementsHeritageClauseElements(declaration);
+                                if (interfaceReferences) {
+                                    for (var _i = 0, interfaceReferences_1 = interfaceReferences; _i < interfaceReferences_1.length; _i++) {
+                                        var typeReference = interfaceReferences_1[_i];
+                                        if (searchTypeReference(typeReference)) {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                            return searchTypeReference(ts.getClassExtendsHeritageClauseElement(declaration));
+                        }
+                        else if (declaration.kind === 230 /* InterfaceDeclaration */) {
+                            if (parentIsInterface) {
+                                return ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), searchTypeReference);
+                            }
+                        }
+                        return false;
+                    });
+                    cachedResults.set(key, inherits);
+                    return inherits;
+                }
+                function searchTypeReference(typeReference) {
+                    if (typeReference) {
+                        var type = checker.getTypeAtLocation(typeReference);
+                        if (type && type.symbol) {
+                            return searchHierarchy(type.symbol);
+                        }
+                    }
+                    return false;
+                }
+            }
+            function getReferencesForSuperKeyword(superKeyword) {
+                var searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
+                if (!searchSpaceNode) {
+                    return undefined;
+                }
+                // Whether 'super' occurs in a static context within a class.
+                var staticFlag = 32 /* Static */;
+                switch (searchSpaceNode.kind) {
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    case 152 /* Constructor */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
+                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
+                        break;
+                    default:
+                        return undefined;
+                }
+                var references = [];
+                var sourceFile = searchSpaceNode.getSourceFile();
+                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode);
+                for (var _i = 0, possiblePositions_3 = possiblePositions; _i < possiblePositions_3.length; _i++) {
+                    var position = possiblePositions_3[_i];
+                    var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
+                    if (!node || node.kind !== 97 /* SuperKeyword */) {
+                        continue;
+                    }
+                    var container = ts.getSuperContainer(node, /*stopOnFunctions*/ false);
+                    // If we have a 'super' container, we must have an enclosing class.
+                    // Now make sure the owning class is the same as the search-space
+                    // and has the same static qualifier as the original 'super's owner.
+                    if (container && (32 /* Static */ & ts.getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
+                        references.push(FindAllReferences.nodeEntry(node));
+                    }
+                }
+                return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol, node: superKeyword }, references: references }];
+            }
+            function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles, cancellationToken) {
+                var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
+                // Whether 'this' occurs in a static context within a class.
+                var staticFlag = 32 /* Static */;
+                switch (searchSpaceNode.kind) {
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        if (ts.isObjectLiteralMethod(searchSpaceNode)) {
+                            break;
+                        }
+                    // falls through
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                    case 152 /* Constructor */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
+                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
+                        break;
+                    case 265 /* SourceFile */:
+                        if (ts.isExternalModule(searchSpaceNode)) {
+                            return undefined;
+                        }
+                    // falls through
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                        break;
+                    // Computed properties in classes are not handled here because references to this are illegal,
+                    // so there is no point finding references to them.
+                    default:
+                        return undefined;
+                }
+                var references = [];
+                var possiblePositions;
+                if (searchSpaceNode.kind === 265 /* SourceFile */) {
+                    ts.forEach(sourceFiles, function (sourceFile) {
+                        cancellationToken.throwIfCancellationRequested();
+                        possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this");
+                        getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references);
+                    });
+                }
+                else {
+                    var sourceFile = searchSpaceNode.getSourceFile();
+                    possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode);
+                    getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
+                }
+                return [{
+                        definition: { type: "this", node: thisOrSuperKeyword },
+                        references: references
+                    }];
+                function getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result) {
+                    ts.forEach(possiblePositions, function (position) {
+                        var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
+                        if (!node || !ts.isThis(node)) {
+                            return;
+                        }
+                        var container = ts.getThisContainer(node, /* includeArrowFunctions */ false);
+                        switch (searchSpaceNode.kind) {
+                            case 186 /* FunctionExpression */:
+                            case 228 /* FunctionDeclaration */:
+                                if (searchSpaceNode.symbol === container.symbol) {
+                                    result.push(FindAllReferences.nodeEntry(node));
+                                }
+                                break;
+                            case 151 /* MethodDeclaration */:
+                            case 150 /* MethodSignature */:
+                                if (ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) {
+                                    result.push(FindAllReferences.nodeEntry(node));
+                                }
+                                break;
+                            case 199 /* ClassExpression */:
+                            case 229 /* ClassDeclaration */:
+                                // Make sure the container belongs to the same class
+                                // and has the appropriate static modifier from the original container.
+                                if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (ts.getModifierFlags(container) & 32 /* Static */) === staticFlag) {
+                                    result.push(FindAllReferences.nodeEntry(node));
+                                }
+                                break;
+                            case 265 /* SourceFile */:
+                                if (container.kind === 265 /* SourceFile */ && !ts.isExternalModule(container)) {
+                                    result.push(FindAllReferences.nodeEntry(node));
+                                }
+                                break;
+                        }
+                    });
+                }
+            }
+            function getReferencesForStringLiteral(node, sourceFiles, cancellationToken) {
+                var references = [];
+                for (var _i = 0, sourceFiles_7 = sourceFiles; _i < sourceFiles_7.length; _i++) {
+                    var sourceFile = sourceFiles_7[_i];
+                    cancellationToken.throwIfCancellationRequested();
+                    var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, node.text);
+                    getReferencesForStringLiteralInFile(sourceFile, node.text, possiblePositions, references);
+                }
+                return [{
+                        definition: { type: "string", node: node },
+                        references: references
+                    }];
+                function getReferencesForStringLiteralInFile(sourceFile, searchText, possiblePositions, references) {
+                    for (var _i = 0, possiblePositions_4 = possiblePositions; _i < possiblePositions_4.length; _i++) {
+                        var position = possiblePositions_4[_i];
+                        var node_7 = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
+                        if (node_7 && node_7.kind === 9 /* StringLiteral */ && node_7.text === searchText) {
+                            references.push(FindAllReferences.nodeEntry(node_7, /*isInString*/ true));
+                        }
+                    }
+                }
+            }
+            // For certain symbol kinds, we need to include other symbols in the search set.
+            // This is not needed when searching for re-exports.
+            function populateSearchSymbolSet(symbol, location, checker, implementations) {
+                // The search set contains at least the current symbol
+                var result = [symbol];
+                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location);
+                if (containingObjectLiteralElement) {
+                    // If the location is name of property symbol from object literal destructuring pattern
+                    // Search the property symbol
+                    //      for ( { property: p2 } of elems) { }
+                    if (containingObjectLiteralElement.kind !== 262 /* ShorthandPropertyAssignment */) {
+                        var propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
+                        if (propertySymbol) {
+                            result.push(propertySymbol);
+                        }
+                    }
+                    // If the location is in a context sensitive location (i.e. in an object literal) try
+                    // to get a contextual type for it, and add the property symbol from the contextual
+                    // type to the search set
+                    ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), function (contextualSymbol) {
+                        ts.addRange(result, checker.getRootSymbols(contextualSymbol));
+                    });
+                    /* Because in short-hand property assignment, location has two meaning : property name and as value of the property
+                     * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
+                     * property name and variable declaration of the identifier.
+                     * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service
+                     * should show both 'name' in 'obj' and 'name' in variable declaration
+                     *      const name = "Foo";
+                     *      const obj = { name };
+                     * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment
+                     * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
+                     * will be included correctly.
+                     */
+                    var shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent);
+                    if (shorthandValueSymbol) {
+                        result.push(shorthandValueSymbol);
+                    }
+                }
+                // If the symbol.valueDeclaration is a property parameter declaration,
+                // we should include both parameter declaration symbol and property declaration symbol
+                // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals.
+                // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members
+                if (symbol.valueDeclaration && symbol.valueDeclaration.kind === 146 /* Parameter */ &&
+                    ts.isParameterPropertyDeclaration(symbol.valueDeclaration)) {
+                    ts.addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name));
+                }
+                // If this is symbol of binding element without propertyName declaration in Object binding pattern
+                // Include the property in the search
+                var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
+                if (bindingElementPropertySymbol) {
+                    result.push(bindingElementPropertySymbol);
+                    addRootSymbols(bindingElementPropertySymbol);
+                }
+                addRootSymbols(symbol);
+                return result;
+                function addRootSymbols(sym) {
+                    // If this is a union property, add all the symbols from all its source symbols in all unioned types.
+                    // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
+                    for (var _i = 0, _a = checker.getRootSymbols(sym); _i < _a.length; _i++) {
+                        var rootSymbol = _a[_i];
+                        if (rootSymbol !== sym) {
+                            result.push(rootSymbol);
+                        }
+                        // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
+                        if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
+                            getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), checker);
+                        }
+                    }
+                }
+            }
+            /**
+             * Find symbol of the given property-name and add the symbol to the given result array
+             * @param symbol a symbol to start searching for the given propertyName
+             * @param propertyName a name of property to search for
+             * @param result an array of symbol of found property symbols
+             * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
+             *                                The value of previousIterationSymbol is undefined when the function is first called.
+             */
+            function getPropertySymbolsFromBaseTypes(symbol, propertyName, result, previousIterationSymbolsCache, checker) {
+                if (!symbol) {
+                    return;
+                }
+                // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited
+                // This is particularly important for the following cases, so that we do not infinitely visit the same symbol.
+                // For example:
+                //      interface C extends C {
+                //          /*findRef*/propName: string;
+                //      }
+                // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName,
+                // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined,
+                // the function will add any found symbol of the property-name, then its sub-routine will call
+                // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
+                // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
+                if (previousIterationSymbolsCache.has(symbol.escapedName)) {
+                    return;
+                }
+                if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
+                    ts.forEach(symbol.getDeclarations(), function (declaration) {
+                        if (ts.isClassLike(declaration)) {
+                            getPropertySymbolFromTypeReference(ts.getClassExtendsHeritageClauseElement(declaration));
+                            ts.forEach(ts.getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference);
+                        }
+                        else if (declaration.kind === 230 /* InterfaceDeclaration */) {
+                            ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference);
+                        }
+                    });
+                }
+                return;
+                function getPropertySymbolFromTypeReference(typeReference) {
+                    if (typeReference) {
+                        var type = checker.getTypeAtLocation(typeReference);
+                        if (type) {
+                            var propertySymbol = checker.getPropertyOfType(type, propertyName);
+                            if (propertySymbol) {
+                                result.push.apply(result, checker.getRootSymbols(propertySymbol));
+                            }
+                            // Visit the typeReference as well to see if it directly or indirectly use that property
+                            previousIterationSymbolsCache.set(symbol.escapedName, symbol);
+                            getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache, checker);
+                        }
+                    }
+                }
+            }
+            function getRelatedSymbol(search, referenceSymbol, referenceLocation, state) {
+                if (search.includes(referenceSymbol)) {
+                    return referenceSymbol;
+                }
+                // If the reference location is in an object literal, try to get the contextual type for the
+                // object literal, lookup the property symbol in the contextual type, and use this symbol to
+                // compare to our searchSymbol
+                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(referenceLocation);
+                if (containingObjectLiteralElement) {
+                    var contextualSymbol = ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, state.checker), function (contextualSymbol) {
+                        return ts.find(state.checker.getRootSymbols(contextualSymbol), search.includes);
+                    });
+                    if (contextualSymbol) {
+                        return contextualSymbol;
+                    }
+                    // If the reference location is the name of property from object literal destructuring pattern
+                    // Get the property symbol from the object literal's type and look if thats the search symbol
+                    // In below eg. get 'property' from type of elems iterating type
+                    //      for ( { property: p2 } of elems) { }
+                    var propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, state.checker);
+                    if (propertySymbol && search.includes(propertySymbol)) {
+                        return propertySymbol;
+                    }
+                }
+                // If the reference location is the binding element and doesn't have property name
+                // then include the binding element in the related symbols
+                //      let { a } : { a };
+                var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, state.checker);
+                if (bindingElementPropertySymbol) {
+                    var fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
+                    if (fromBindingElement)
+                        return fromBindingElement;
+                }
+                return findRootSymbol(referenceSymbol);
+                function findRootSymbol(sym) {
+                    // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
+                    // Or a union property, use its underlying unioned symbols
+                    return ts.forEach(state.checker.getRootSymbols(sym), function (rootSymbol) {
+                        // if it is in the list, then we are done
+                        if (search.includes(rootSymbol)) {
+                            return rootSymbol;
+                        }
+                        // Finally, try all properties with the same name in any type the containing type extended or implemented, and
+                        // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the
+                        // parent symbol
+                        if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
+                            // Parents will only be defined if implementations is true
+                            if (search.parents && !ts.some(search.parents, function (parent) { return explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker); })) {
+                                return undefined;
+                            }
+                            var result = [];
+                            getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), state.checker);
+                            return ts.find(result, search.includes);
+                        }
+                        return undefined;
+                    });
+                }
+            }
+            function getNameFromObjectLiteralElement(node) {
+                if (node.name.kind === 144 /* ComputedPropertyName */) {
+                    var nameExpression = node.name.expression;
+                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
+                    if (ts.isStringOrNumericLiteral(nameExpression)) {
+                        return nameExpression.text;
+                    }
+                    return undefined;
+                }
+                return ts.getTextOfIdentifierOrLiteral(node.name);
+            }
+            /** Gets all symbols for one property. Does not get symbols for every property. */
+            function getPropertySymbolsFromContextualType(node, checker) {
+                var objectLiteral = node.parent;
+                var contextualType = checker.getContextualType(objectLiteral);
+                var name = getNameFromObjectLiteralElement(node);
+                if (name && contextualType) {
+                    var result_6 = [];
+                    var symbol = contextualType.getProperty(name);
+                    if (symbol) {
+                        result_6.push(symbol);
+                    }
+                    if (contextualType.flags & 65536 /* Union */) {
+                        ts.forEach(contextualType.types, function (t) {
+                            var symbol = t.getProperty(name);
+                            if (symbol) {
+                                result_6.push(symbol);
+                            }
+                        });
+                    }
+                    return result_6;
+                }
+                return undefined;
+            }
+            /**
+             * Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations
+             * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class
+             * then we need to widen the search to include type positions as well.
+             * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated
+             * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module)
+             * do not intersect in any of the three spaces.
+             */
+            function getIntersectingMeaningFromDeclarations(meaning, declarations) {
+                if (declarations) {
+                    var lastIterationMeaning = void 0;
+                    do {
+                        // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module]
+                        // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module
+                        // intersects with the class in the value space.
+                        // To achieve that we will keep iterating until the result stabilizes.
+                        // Remember the last meaning
+                        lastIterationMeaning = meaning;
+                        for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) {
+                            var declaration = declarations_10[_i];
+                            var declarationMeaning = ts.getMeaningFromDeclaration(declaration);
+                            if (declarationMeaning & meaning) {
+                                meaning |= declarationMeaning;
+                            }
+                        }
+                    } while (meaning !== lastIterationMeaning);
+                }
+                return meaning;
+            }
+            function isImplementation(node) {
+                if (!node) {
+                    return false;
+                }
+                else if (ts.isVariableLike(node)) {
+                    if (node.initializer) {
+                        return true;
+                    }
+                    else if (node.kind === 226 /* VariableDeclaration */) {
+                        var parentStatement = getParentStatementOfVariableDeclaration(node);
+                        return parentStatement && ts.hasModifier(parentStatement, 2 /* Ambient */);
+                    }
+                }
+                else if (ts.isFunctionLike(node)) {
+                    return !!node.body || ts.hasModifier(node, 2 /* Ambient */);
+                }
+                else {
+                    switch (node.kind) {
+                        case 229 /* ClassDeclaration */:
+                        case 199 /* ClassExpression */:
+                        case 232 /* EnumDeclaration */:
+                        case 233 /* ModuleDeclaration */:
+                            return true;
+                    }
+                }
+                return false;
+            }
+            function getParentStatementOfVariableDeclaration(node) {
+                if (node.parent && node.parent.parent && node.parent.parent.kind === 208 /* VariableStatement */) {
+                    ts.Debug.assert(node.parent.kind === 227 /* VariableDeclarationList */);
+                    return node.parent.parent;
+                }
+            }
+            function getReferenceEntriesForShorthandPropertyAssignment(node, checker, addReference) {
+                var refSymbol = checker.getSymbolAtLocation(node);
+                var shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration);
+                if (shorthandSymbol) {
+                    for (var _i = 0, _a = shorthandSymbol.getDeclarations(); _i < _a.length; _i++) {
+                        var declaration = _a[_i];
+                        if (ts.getMeaningFromDeclaration(declaration) & 1 /* Value */) {
+                            addReference(declaration);
+                        }
+                    }
+                }
+            }
+            Core.getReferenceEntriesForShorthandPropertyAssignment = getReferenceEntriesForShorthandPropertyAssignment;
+            function forEachDescendantOfKind(node, kind, action) {
+                ts.forEachChild(node, function (child) {
+                    if (child.kind === kind) {
+                        action(child);
+                    }
+                    forEachDescendantOfKind(child, kind, action);
+                });
+            }
+            /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
+            function tryGetClassByExtendingIdentifier(node) {
+                return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent);
+            }
+            function isNameOfExternalModuleImportOrDeclaration(node) {
+                if (node.kind === 9 /* StringLiteral */) {
+                    return ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node);
+                }
+                return false;
+            }
+            /**
+             * If we are just looking for implementations and this is a property access expression, we need to get the
+             * symbol of the local type of the symbol the property is being accessed on. This is because our search
+             * symbol may have a different parent symbol if the local type's symbol does not declare the property
+             * being accessed (i.e. it is declared in some parent class or interface)
+             */
+            function getParentSymbolsOfPropertyAccess(location, symbol, checker) {
+                var propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(location);
+                if (!propertyAccessExpression) {
+                    return undefined;
+                }
+                var localParentType = checker.getTypeAtLocation(propertyAccessExpression.expression);
+                if (!localParentType) {
+                    return undefined;
+                }
+                if (localParentType.symbol && localParentType.symbol.flags & (32 /* Class */ | 64 /* Interface */) && localParentType.symbol !== symbol.parent) {
+                    return [localParentType.symbol];
+                }
+                else if (localParentType.flags & 196608 /* UnionOrIntersection */) {
+                    return getSymbolsForClassAndInterfaceComponents(localParentType);
+                }
+            }
+        })(Core = FindAllReferences.Core || (FindAllReferences.Core = {}));
+    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var GoToDefinition;
+    (function (GoToDefinition) {
+        function getDefinitionAtPosition(program, sourceFile, position) {
+            /// Triple slash reference comments
+            var comment = findReferenceInPosition(sourceFile.referencedFiles, position);
+            if (comment) {
+                var referenceFile = ts.tryResolveScriptReference(program, sourceFile, comment);
+                if (referenceFile) {
+                    return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)];
+                }
+                // Might still be on jsdoc, so keep looking.
+            }
+            // Type reference directives
+            var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
+            if (typeReferenceDirective) {
+                var referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName);
+                return referenceFile && referenceFile.resolvedFileName &&
+                    [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)];
+            }
+            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+            if (node === sourceFile) {
+                return undefined;
+            }
+            // Labels
+            if (ts.isJumpStatementTarget(node)) {
+                var labelName = node.text;
+                var label = ts.getTargetLabel(node.parent, labelName);
+                return label ? [createDefinitionInfoFromName(label, "label" /* label */, labelName, /*containerName*/ undefined)] : undefined;
+            }
+            var typeChecker = program.getTypeChecker();
+            var calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
+            if (calledDeclaration) {
+                return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)];
+            }
+            var symbol = typeChecker.getSymbolAtLocation(node);
+            // Could not find a symbol e.g. node is string or number keyword,
+            // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
+            if (!symbol) {
+                return undefined;
+            }
+            // If this is an alias, and the request came at the declaration location
+            // get the aliased symbol instead. This allows for goto def on an import e.g.
+            //   import {A, B} from "mod";
+            // to jump to the implementation directly.
+            if (symbol.flags & 2097152 /* Alias */ && shouldSkipAlias(node, symbol.declarations[0])) {
+                var aliased = typeChecker.getAliasedSymbol(symbol);
+                if (aliased.declarations) {
+                    symbol = aliased;
+                }
+            }
+            // Because name in short-hand property assignment has two different meanings: property name and property value,
+            // using go-to-definition at such position should go to the variable declaration of the property value rather than
+            // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
+            // is performed at the location of property access, we would like to go to definition of the property in the short-hand
+            // assignment. This case and others are handled by the following code.
+            if (node.parent.kind === 262 /* ShorthandPropertyAssignment */) {
+                var shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
+                if (!shorthandSymbol) {
+                    return [];
+                }
+                var shorthandDeclarations = shorthandSymbol.getDeclarations();
+                var shorthandSymbolKind_1 = ts.SymbolDisplay.getSymbolKind(typeChecker, shorthandSymbol, node);
+                var shorthandSymbolName_1 = typeChecker.symbolToString(shorthandSymbol);
+                var shorthandContainerName_1 = typeChecker.symbolToString(symbol.parent, node);
+                return ts.map(shorthandDeclarations, function (declaration) { return createDefinitionInfo(declaration, shorthandSymbolKind_1, shorthandSymbolName_1, shorthandContainerName_1); });
+            }
+            // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
+            // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
+            // and return the property declaration for the referenced property.
+            // For example:
+            //      import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
+            //
+            //      function bar<T>(onfulfilled: (value: T) => void) { //....}
+            //      interface Test {
+            //          pr/*destination*/op1: number
+            //      }
+            //      bar<Test>(({pr/*goto*/op1})=>{});
+            if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
+                (node === (node.parent.propertyName || node.parent.name))) {
+                var type = typeChecker.getTypeAtLocation(node.parent.parent);
+                if (type) {
+                    var propSymbols = ts.getPropertySymbolsFromType(type, node);
+                    if (propSymbols) {
+                        return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); });
+                    }
+                }
+            }
+            // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
+            // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
+            // For example
+            //      interface Props{
+            //          /*first*/prop1: number
+            //          prop2: boolean
+            //      }
+            //      function Foo(arg: Props) {}
+            //      Foo( { pr/*1*/op1: 10, prop2: true })
+            var element = ts.getContainingObjectLiteralElement(node);
+            if (element && typeChecker.getContextualType(element.parent)) {
+                return ts.flatMap(ts.getPropertySymbolsFromContextualType(typeChecker, element), function (propertySymbol) {
+                    return getDefinitionFromSymbol(typeChecker, propertySymbol, node);
+                });
+            }
+            return getDefinitionFromSymbol(typeChecker, symbol, node);
+        }
+        GoToDefinition.getDefinitionAtPosition = getDefinitionAtPosition;
+        /// Goto type
+        function getTypeDefinitionAtPosition(typeChecker, sourceFile, position) {
+            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+            if (node === sourceFile) {
+                return undefined;
+            }
+            var symbol = typeChecker.getSymbolAtLocation(node);
+            if (!symbol) {
+                return undefined;
+            }
+            var type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
+            if (!type) {
+                return undefined;
+            }
+            if (type.flags & 65536 /* Union */ && !(type.flags & 16 /* Enum */)) {
+                var result_7 = [];
+                ts.forEach(type.types, function (t) {
+                    if (t.symbol) {
+                        ts.addRange(/*to*/ result_7, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node));
+                    }
+                });
+                return result_7;
+            }
+            if (!type.symbol) {
+                return undefined;
+            }
+            return getDefinitionFromSymbol(typeChecker, type.symbol, node);
+        }
+        GoToDefinition.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition;
+        // Go to the original declaration for cases:
+        //
+        //   (1) when the aliased symbol was declared in the location(parent).
+        //   (2) when the aliased symbol is originating from an import.
+        //
+        function shouldSkipAlias(node, declaration) {
+            if (node.kind !== 71 /* Identifier */) {
+                return false;
+            }
+            if (node.parent === declaration) {
+                return true;
+            }
+            switch (declaration.kind) {
+                case 239 /* ImportClause */:
+                case 237 /* ImportEqualsDeclaration */:
+                    return true;
+                case 242 /* ImportSpecifier */:
+                    return declaration.parent.kind === 241 /* NamedImports */;
+                default:
+                    return false;
+            }
+        }
+        function getDefinitionFromSymbol(typeChecker, symbol, node) {
+            var result = [];
+            var declarations = symbol.getDeclarations();
+            var _a = getSymbolInfo(typeChecker, symbol, node), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName;
+            if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
+                !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
+                // Just add all the declarations.
+                ts.forEach(declarations, function (declaration) {
+                    result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
+                });
+            }
+            return result;
+            function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) {
+                // Applicable only if we are in a new expression, or we are on a constructor declaration
+                // and in either case the symbol has a construct signature definition, i.e. class
+                if (ts.isNewExpressionTarget(location) || location.kind === 123 /* ConstructorKeyword */) {
+                    if (symbol.flags & 32 /* Class */) {
+                        // Find the first class-like declaration and try to get the construct signature.
+                        for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) {
+                            var declaration = _a[_i];
+                            if (ts.isClassLike(declaration)) {
+                                return tryAddSignature(declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
+                            }
+                        }
+                        ts.Debug.fail("Expected declaration to have at least one class-like declaration");
+                    }
+                }
+                return false;
+            }
+            function tryAddCallSignature(symbol, location, symbolKind, symbolName, containerName, result) {
+                if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location) || ts.isNameOfFunctionDeclaration(location)) {
+                    return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
+                }
+                return false;
+            }
+            function tryAddSignature(signatureDeclarations, selectConstructors, symbolKind, symbolName, containerName, result) {
+                if (!signatureDeclarations) {
+                    return false;
+                }
+                var declarations = [];
+                var definition;
+                for (var _i = 0, signatureDeclarations_1 = signatureDeclarations; _i < signatureDeclarations_1.length; _i++) {
+                    var d = signatureDeclarations_1[_i];
+                    if (selectConstructors ? d.kind === 152 /* Constructor */ : isSignatureDeclaration(d)) {
+                        declarations.push(d);
+                        if (d.body)
+                            definition = d;
+                    }
+                }
+                if (declarations.length) {
+                    result.push(createDefinitionInfo(definition || ts.lastOrUndefined(declarations), symbolKind, symbolName, containerName));
+                    return true;
+                }
+                return false;
+            }
+        }
+        function isSignatureDeclaration(node) {
+            switch (node.kind) {
+                case 152 /* Constructor */:
+                case 228 /* FunctionDeclaration */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+        /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */
+        function createDefinitionInfo(node, symbolKind, symbolName, containerName) {
+            return createDefinitionInfoFromName(ts.getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName);
+        }
+        /** Creates a DefinitionInfo directly from the name of a declaration. */
+        function createDefinitionInfoFromName(name, symbolKind, symbolName, containerName) {
+            var sourceFile = name.getSourceFile();
+            return {
+                fileName: sourceFile.fileName,
+                textSpan: ts.createTextSpanFromNode(name, sourceFile),
+                kind: symbolKind,
+                name: symbolName,
+                containerKind: undefined,
+                containerName: containerName
+            };
+        }
+        function getSymbolInfo(typeChecker, symbol, node) {
+            return {
+                symbolName: typeChecker.symbolToString(symbol),
+                symbolKind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node),
+                containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : ""
+            };
+        }
+        function createDefinitionFromSignatureDeclaration(typeChecker, decl) {
+            var _a = getSymbolInfo(typeChecker, decl.symbol, decl), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName;
+            return createDefinitionInfo(decl, symbolKind, symbolName, containerName);
+        }
+        function findReferenceInPosition(refs, pos) {
+            for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
+                var ref = refs_1[_i];
+                if (ref.pos <= pos && pos <= ref.end) {
+                    return ref;
+                }
+            }
+            return undefined;
+        }
+        function getDefinitionInfoForFileReference(name, targetFileName) {
+            return {
+                fileName: targetFileName,
+                textSpan: ts.createTextSpanFromBounds(0, 0),
+                kind: "script" /* scriptElement */,
+                name: name,
+                containerName: undefined,
+                containerKind: undefined
+            };
+        }
+        /** Returns a CallLikeExpression where `node` is the target being invoked. */
+        function getAncestorCallLikeExpression(node) {
+            var target = climbPastManyPropertyAccesses(node);
+            var callLike = target.parent;
+            return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target && callLike;
+        }
+        function climbPastManyPropertyAccesses(node) {
+            return ts.isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
+        }
+        function tryGetSignatureDeclaration(typeChecker, node) {
+            var callLike = getAncestorCallLikeExpression(node);
+            var signature = callLike && typeChecker.getResolvedSignature(callLike);
+            if (signature) {
+                var decl = signature.declaration;
+                if (decl && isSignatureDeclaration(decl)) {
+                    return decl;
+                }
+            }
+            // Don't go to a function type, go to the value having that type.
+            return undefined;
+        }
+    })(GoToDefinition = ts.GoToDefinition || (ts.GoToDefinition = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var JsDoc;
+    (function (JsDoc) {
+        var jsDocTagNames = [
+            "augments",
+            "author",
+            "argument",
+            "borrows",
+            "class",
+            "constant",
+            "constructor",
+            "constructs",
+            "default",
+            "deprecated",
+            "description",
+            "event",
+            "example",
+            "extends",
+            "field",
+            "fileOverview",
+            "function",
+            "ignore",
+            "inner",
+            "lends",
+            "link",
+            "memberOf",
+            "method",
+            "name",
+            "namespace",
+            "param",
+            "private",
+            "prop",
+            "property",
+            "public",
+            "requires",
+            "returns",
+            "see",
+            "since",
+            "static",
+            "throws",
+            "type",
+            "typedef",
+            "version"
+        ];
+        var jsDocTagNameCompletionEntries;
+        var jsDocTagCompletionEntries;
+        function getJsDocCommentsFromDeclarations(declarations) {
+            // Only collect doc comments from duplicate declarations once:
+            // In case of a union property there might be same declaration multiple times
+            // which only varies in type parameter
+            // Eg. const a: Array<string> | Array<number>; a.length
+            // The property length will have two declarations of property length coming
+            // from Array<T> - Array<string> and Array<number>
+            var documentationComment = [];
+            forEachUnique(declarations, function (declaration) {
+                ts.forEach(ts.getAllJSDocs(declaration), function (doc) {
+                    if (doc.comment) {
+                        if (documentationComment.length) {
+                            documentationComment.push(ts.lineBreakPart());
+                        }
+                        documentationComment.push(ts.textPart(doc.comment));
+                    }
+                });
+            });
+            return documentationComment;
+        }
+        JsDoc.getJsDocCommentsFromDeclarations = getJsDocCommentsFromDeclarations;
+        function getJsDocTagsFromDeclarations(declarations) {
+            // Only collect doc comments from duplicate declarations once.
+            var tags = [];
+            forEachUnique(declarations, function (declaration) {
+                for (var _i = 0, _a = ts.getJSDocTags(declaration); _i < _a.length; _i++) {
+                    var tag = _a[_i];
+                    if (tag.kind === 276 /* JSDocTag */) {
+                        tags.push({ name: tag.tagName.text, text: tag.comment });
+                    }
+                }
+            });
+            return tags;
+        }
+        JsDoc.getJsDocTagsFromDeclarations = getJsDocTagsFromDeclarations;
+        /**
+         * Iterates through 'array' by index and performs the callback on each element of array until the callback
+         * returns a truthy value, then returns that value.
+         * If no such value is found, the callback is applied to each element of array and undefined is returned.
+         */
+        function forEachUnique(array, callback) {
+            if (array) {
+                for (var i = 0; i < array.length; i++) {
+                    if (ts.indexOf(array, array[i]) === i) {
+                        var result = callback(array[i], i);
+                        if (result) {
+                            return result;
+                        }
+                    }
+                }
+            }
+            return undefined;
+        }
+        function getJSDocTagNameCompletions() {
+            return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
+                return {
+                    name: tagName,
+                    kind: "keyword" /* keyword */,
+                    kindModifiers: "",
+                    sortText: "0",
+                };
+            }));
+        }
+        JsDoc.getJSDocTagNameCompletions = getJSDocTagNameCompletions;
+        function getJSDocTagCompletions() {
+            return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
+                return {
+                    name: "@" + tagName,
+                    kind: "keyword" /* keyword */,
+                    kindModifiers: "",
+                    sortText: "0"
+                };
+            }));
+        }
+        JsDoc.getJSDocTagCompletions = getJSDocTagCompletions;
+        function getJSDocParameterNameCompletions(tag) {
+            if (!ts.isIdentifier(tag.name)) {
+                return ts.emptyArray;
+            }
+            var nameThusFar = tag.name.text;
+            var jsdoc = tag.parent;
+            var fn = jsdoc.parent;
+            if (!ts.isFunctionLike(fn))
+                return [];
+            return ts.mapDefined(fn.parameters, function (param) {
+                if (!ts.isIdentifier(param.name))
+                    return undefined;
+                var name = param.name.text;
+                if (jsdoc.tags.some(function (t) { return t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name; })
+                    || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) {
+                    return undefined;
+                }
+                return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", sortText: "0" };
+            });
+        }
+        JsDoc.getJSDocParameterNameCompletions = getJSDocParameterNameCompletions;
+        /**
+         * Checks if position points to a valid position to add JSDoc comments, and if so,
+         * returns the appropriate template. Otherwise returns an empty string.
+         * Valid positions are
+         *      - outside of comments, statements, and expressions, and
+         *      - preceding a:
+         *          - function/constructor/method declaration
+         *          - class declarations
+         *          - variable statements
+         *          - namespace declarations
+         *
+         * Hosts should ideally check that:
+         * - The line is all whitespace up to 'position' before performing the insertion.
+         * - If the keystroke sequence "/\*\*" induced the call, we also check that the next
+         * non-whitespace character is '*', which (approximately) indicates whether we added
+         * the second '*' to complete an existing (JSDoc) comment.
+         * @param fileName The file in which to perform the check.
+         * @param position The (character-indexed) position in the file where the check should
+         * be performed.
+         */
+        function getDocCommentTemplateAtPosition(newLine, sourceFile, position) {
+            // Check if in a context where we don't want to perform any insertion
+            if (ts.isInString(sourceFile, position) || ts.isInComment(sourceFile, position) || ts.hasDocComment(sourceFile, position)) {
+                return undefined;
+            }
+            var tokenAtPos = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+            var tokenStart = tokenAtPos.getStart();
+            if (!tokenAtPos || tokenStart < position) {
+                return undefined;
+            }
+            var commentOwnerInfo = getCommentOwnerInfo(tokenAtPos);
+            if (!commentOwnerInfo) {
+                return undefined;
+            }
+            var commentOwner = commentOwnerInfo.commentOwner, parameters = commentOwnerInfo.parameters;
+            if (commentOwner.getStart() < position) {
+                return undefined;
+            }
+            var posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
+            var lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
+            // replace non-whitespace characters in prefix with spaces.
+            var indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, function () { return " "; });
+            var isJavaScriptFile = ts.hasJavaScriptFileExtension(sourceFile.fileName);
+            var docParams = "";
+            if (parameters) {
+                for (var i = 0; i < parameters.length; i++) {
+                    var currentName = parameters[i].name;
+                    var paramName = currentName.kind === 71 /* Identifier */ ?
+                        currentName.escapedText :
+                        "param" + i;
+                    if (isJavaScriptFile) {
+                        docParams += indentationStr + " * @param {any} " + paramName + newLine;
+                    }
+                    else {
+                        docParams += indentationStr + " * @param " + paramName + newLine;
+                    }
+                }
+            }
+            // A doc comment consists of the following
+            // * The opening comment line
+            // * the first line (without a param) for the object's untagged info (this is also where the caret ends up)
+            // * the '@param'-tagged lines
+            // * TODO: other tags.
+            // * the closing comment line
+            // * if the caret was directly in front of the object, then we add an extra line and indentation.
+            var preamble = "/**" + newLine +
+                indentationStr + " * ";
+            var result = preamble + newLine +
+                docParams +
+                indentationStr + " */" +
+                (tokenStart === position ? newLine + indentationStr : "");
+            return { newText: result, caretOffset: preamble.length };
+        }
+        JsDoc.getDocCommentTemplateAtPosition = getDocCommentTemplateAtPosition;
+        function getCommentOwnerInfo(tokenAtPos) {
+            // TODO: add support for:
+            // - enums/enum members
+            // - interfaces
+            // - property declarations
+            // - potentially property assignments
+            for (var commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
+                switch (commentOwner.kind) {
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 152 /* Constructor */:
+                        var parameters = commentOwner.parameters;
+                        return { commentOwner: commentOwner, parameters: parameters };
+                    case 229 /* ClassDeclaration */:
+                        return { commentOwner: commentOwner };
+                    case 208 /* VariableStatement */: {
+                        var varStatement = commentOwner;
+                        var varDeclarations = varStatement.declarationList.declarations;
+                        var parameters_1 = varDeclarations.length === 1 && varDeclarations[0].initializer
+                            ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
+                            : undefined;
+                        return { commentOwner: commentOwner, parameters: parameters_1 };
+                    }
+                    case 265 /* SourceFile */:
+                        return undefined;
+                    case 233 /* ModuleDeclaration */:
+                        // If in walking up the tree, we hit a a nested namespace declaration,
+                        // then we must be somewhere within a dotted namespace name; however we don't
+                        // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
+                        return commentOwner.parent.kind === 233 /* ModuleDeclaration */ ? undefined : { commentOwner: commentOwner };
+                    case 194 /* BinaryExpression */: {
+                        var be = commentOwner;
+                        if (ts.getSpecialPropertyAssignmentKind(be) === 0 /* None */) {
+                            return undefined;
+                        }
+                        var parameters_2 = ts.isFunctionLike(be.right) ? be.right.parameters : ts.emptyArray;
+                        return { commentOwner: commentOwner, parameters: parameters_2 };
+                    }
+                }
+            }
+        }
+        /**
+         * Digs into an an initializer or RHS operand of an assignment operation
+         * to get the parameters of an apt signature corresponding to a
+         * function expression or a class expression.
+         *
+         * @param rightHandSide the expression which may contain an appropriate set of parameters
+         * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
+         */
+        function getParametersFromRightHandSideOfAssignment(rightHandSide) {
+            while (rightHandSide.kind === 185 /* ParenthesizedExpression */) {
+                rightHandSide = rightHandSide.expression;
+            }
+            switch (rightHandSide.kind) {
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                    return rightHandSide.parameters;
+                case 199 /* ClassExpression */:
+                    for (var _i = 0, _a = rightHandSide.members; _i < _a.length; _i++) {
+                        var member = _a[_i];
+                        if (member.kind === 152 /* Constructor */) {
+                            return member.parameters;
+                        }
+                    }
+                    break;
+            }
+            return ts.emptyArray;
+        }
+    })(JsDoc = ts.JsDoc || (ts.JsDoc = {}));
+})(ts || (ts = {}));
+// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
+// See LICENSE.txt in the project root for complete license information.
+/// <reference path='../compiler/types.ts' />
+/// <reference path='../compiler/core.ts' />
+/// <reference path='../compiler/commandLineParser.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var JsTyping;
+    (function (JsTyping) {
+        /* @internal */
+        JsTyping.nodeCoreModuleList = [
+            "buffer", "querystring", "events", "http", "cluster",
+            "zlib", "os", "https", "punycode", "repl", "readline",
+            "vm", "child_process", "url", "dns", "net",
+            "dgram", "fs", "path", "string_decoder", "tls",
+            "crypto", "stream", "util", "assert", "tty", "domain",
+            "constants", "process", "v8", "timers", "console"
+        ];
+        var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList);
+        function loadSafeList(host, safeListPath) {
+            var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
+            return ts.createMapFromTemplate(result.config);
+        }
+        JsTyping.loadSafeList = loadSafeList;
+        function loadTypesMap(host, typesMapPath) {
+            var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); });
+            if (result.config) {
+                return ts.createMapFromTemplate(result.config.simpleMap);
+            }
+            return undefined;
+        }
+        JsTyping.loadTypesMap = loadTypesMap;
+        /**
+         * @param host is the object providing I/O related operations.
+         * @param fileNames are the file names that belong to the same project
+         * @param projectRootPath is the path to the project root directory
+         * @param safeListPath is the path used to retrieve the safe list
+         * @param packageNameToTypingLocation is the map of package names to their cached typing locations
+         * @param typeAcquisition is used to customize the typing acquisition process
+         * @param compilerOptions are used as a source for typing inference
+         */
+        function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports) {
+            if (!typeAcquisition || !typeAcquisition.enable) {
+                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
+            }
+            // A typing name to typing file path mapping
+            var inferredTypings = ts.createMap();
+            // Only infer typings for .js and .jsx files
+            fileNames = ts.mapDefined(fileNames, function (fileName) {
+                var path = ts.normalizePath(fileName);
+                if (ts.hasJavaScriptFileExtension(path)) {
+                    return path;
+                }
+            });
+            var filesToWatch = [];
+            if (typeAcquisition.include)
+                addInferredTypings(typeAcquisition.include, "Explicitly included types");
+            var exclude = typeAcquisition.exclude || [];
+            // Directories to search for package.json, bower.json and other typing information
+            var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath);
+            possibleSearchDirs.set(projectRootPath, true);
+            possibleSearchDirs.forEach(function (_true, searchDir) {
+                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
+                getTypingNamesFromJson(packageJsonPath, filesToWatch);
+                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
+                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
+                var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components");
+                getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);
+                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
+                getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
+            });
+            getTypingNamesFromSourceFileNames(fileNames);
+            // add typings for unresolved imports
+            if (unresolvedImports) {
+                var module = ts.deduplicate(unresolvedImports.map(function (moduleId) { return nodeCoreModules.has(moduleId) ? "node" : moduleId; }));
+                addInferredTypings(module, "Inferred typings from unresolved imports");
+            }
+            // Add the cached typing locations for inferred typings that are already installed
+            packageNameToTypingLocation.forEach(function (typingLocation, name) {
+                if (inferredTypings.has(name) && inferredTypings.get(name) === undefined) {
+                    inferredTypings.set(name, typingLocation);
+                }
+            });
+            // Remove typings that the user has added to the exclude list
+            for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) {
+                var excludeTypingName = exclude_1[_i];
+                var didDelete = inferredTypings.delete(excludeTypingName);
+                if (didDelete && log)
+                    log("Typing for " + excludeTypingName + " is in exclude list, will be ignored.");
+            }
+            var newTypingNames = [];
+            var cachedTypingPaths = [];
+            inferredTypings.forEach(function (inferred, typing) {
+                if (inferred !== undefined) {
+                    cachedTypingPaths.push(inferred);
+                }
+                else {
+                    newTypingNames.push(typing);
+                }
+            });
+            var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
+            if (log)
+                log("Result: " + JSON.stringify(result));
+            return result;
+            function addInferredTyping(typingName) {
+                if (!inferredTypings.has(typingName)) {
+                    inferredTypings.set(typingName, undefined);
+                }
+            }
+            function addInferredTypings(typingNames, message) {
+                if (log)
+                    log(message + ": " + JSON.stringify(typingNames));
+                ts.forEach(typingNames, addInferredTyping);
+            }
+            /**
+             * Get the typing info from common package manager json files like package.json or bower.json
+             */
+            function getTypingNamesFromJson(jsonPath, filesToWatch) {
+                if (!host.fileExists(jsonPath)) {
+                    return;
+                }
+                filesToWatch.push(jsonPath);
+                var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config;
+                var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys);
+                addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies");
+            }
+            /**
+             * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js"
+             * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred
+             * to the 'angular-route' typing name.
+             * @param fileNames are the names for source files in the project
+             */
+            function getTypingNamesFromSourceFileNames(fileNames) {
+                var fromFileNames = ts.mapDefined(fileNames, function (j) {
+                    if (!ts.hasJavaScriptFileExtension(j))
+                        return undefined;
+                    var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase()));
+                    var cleanedTypingName = inferredTypingName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, "");
+                    return safeList.get(cleanedTypingName);
+                });
+                if (fromFileNames.length) {
+                    addInferredTypings(fromFileNames, "Inferred typings from file names");
+                }
+                var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); });
+                if (hasJsxFile) {
+                    if (log)
+                        log("Inferred 'react' typings due to presence of '.jsx' extension");
+                    addInferredTyping("react");
+                }
+            }
+            /**
+             * Infer typing names from packages folder (ex: node_module, bower_components)
+             * @param packagesFolderPath is the path to the packages folder
+             */
+            function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) {
+                filesToWatch.push(packagesFolderPath);
+                // Todo: add support for ModuleResolutionHost too
+                if (!host.directoryExists(packagesFolderPath)) {
+                    return;
+                }
+                // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
+                var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
+                if (log)
+                    log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames));
+                var packageNames = [];
+                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
+                    var fileName = fileNames_1[_i];
+                    var normalizedFileName = ts.normalizePath(fileName);
+                    var baseFileName = ts.getBaseFileName(normalizedFileName);
+                    if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
+                        continue;
+                    }
+                    var result_8 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
+                    var packageJson = result_8.config;
+                    // npm 3's package.json contains a "_requiredBy" field
+                    // we should include all the top level module names for npm 2, and only module names whose
+                    // "_requiredBy" field starts with "#" or equals "/" for npm 3.
+                    if (baseFileName === "package.json" && packageJson._requiredBy &&
+                        ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) {
+                        continue;
+                    }
+                    // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used
+                    // to download d.ts files from DefinitelyTyped
+                    if (!packageJson.name) {
+                        continue;
+                    }
+                    var ownTypes = packageJson.types || packageJson.typings;
+                    if (ownTypes) {
+                        var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName));
+                        if (log)
+                            log("    Package '" + packageJson.name + "' provides its own types.");
+                        inferredTypings.set(packageJson.name, absolutePath);
+                    }
+                    else {
+                        packageNames.push(packageJson.name);
+                    }
+                }
+                addInferredTypings(packageNames, "    Found package names");
+            }
+        }
+        JsTyping.discoverTypings = discoverTypings;
+        var PackageNameValidationResult;
+        (function (PackageNameValidationResult) {
+            PackageNameValidationResult[PackageNameValidationResult["Ok"] = 0] = "Ok";
+            PackageNameValidationResult[PackageNameValidationResult["ScopedPackagesNotSupported"] = 1] = "ScopedPackagesNotSupported";
+            PackageNameValidationResult[PackageNameValidationResult["EmptyName"] = 2] = "EmptyName";
+            PackageNameValidationResult[PackageNameValidationResult["NameTooLong"] = 3] = "NameTooLong";
+            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithDot"] = 4] = "NameStartsWithDot";
+            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithUnderscore"] = 5] = "NameStartsWithUnderscore";
+            PackageNameValidationResult[PackageNameValidationResult["NameContainsNonURISafeCharacters"] = 6] = "NameContainsNonURISafeCharacters";
+        })(PackageNameValidationResult = JsTyping.PackageNameValidationResult || (JsTyping.PackageNameValidationResult = {}));
+        var MaxPackageNameLength = 214;
+        /**
+         * Validates package name using rules defined at https://docs.npmjs.com/files/package.json
+         */
+        function validatePackageName(packageName) {
+            if (!packageName) {
+                return 2 /* EmptyName */;
+            }
+            if (packageName.length > MaxPackageNameLength) {
+                return 3 /* NameTooLong */;
+            }
+            if (packageName.charCodeAt(0) === 46 /* dot */) {
+                return 4 /* NameStartsWithDot */;
+            }
+            if (packageName.charCodeAt(0) === 95 /* _ */) {
+                return 5 /* NameStartsWithUnderscore */;
+            }
+            // check if name is scope package like: starts with @ and has one '/' in the middle
+            // scoped packages are not currently supported
+            // TODO: when support will be added we'll need to split and check both scope and package name
+            if (/^@[^/]+\/[^/]+$/.test(packageName)) {
+                return 1 /* ScopedPackagesNotSupported */;
+            }
+            if (encodeURIComponent(packageName) !== packageName) {
+                return 6 /* NameContainsNonURISafeCharacters */;
+            }
+            return 0 /* Ok */;
+        }
+        JsTyping.validatePackageName = validatePackageName;
+        function renderPackageNameValidationFailure(result, typing) {
+            switch (result) {
+                case 2 /* EmptyName */:
+                    return "Package name '" + typing + "' cannot be empty";
+                case 3 /* NameTooLong */:
+                    return "Package name '" + typing + "' should be less than " + MaxPackageNameLength + " characters";
+                case 4 /* NameStartsWithDot */:
+                    return "Package name '" + typing + "' cannot start with '.'";
+                case 5 /* NameStartsWithUnderscore */:
+                    return "Package name '" + typing + "' cannot start with '_'";
+                case 1 /* ScopedPackagesNotSupported */:
+                    return "Package '" + typing + "' is scoped and currently is not supported";
+                case 6 /* NameContainsNonURISafeCharacters */:
+                    return "Package name '" + typing + "' contains non URI safe characters";
+                case 0 /* Ok */:
+                    throw ts.Debug.fail(); // Shouldn't have called this.
+                default:
+                    ts.Debug.assertNever(result);
+            }
+        }
+        JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure;
+    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var NavigateTo;
+    (function (NavigateTo) {
+        function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles) {
+            var patternMatcher = ts.createPatternMatcher(searchValue);
+            var rawItems = [];
+            var _loop_6 = function (sourceFile) {
+                cancellationToken.throwIfCancellationRequested();
+                if (excludeDtsFiles && ts.fileExtensionIs(sourceFile.fileName, ".d.ts" /* Dts */)) {
+                    return "continue";
+                }
+                ts.forEachEntry(sourceFile.getNamedDeclarations(), function (declarations, name) {
+                    getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, sourceFile.fileName, rawItems);
+                });
+            };
+            // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
+            for (var _i = 0, sourceFiles_8 = sourceFiles; _i < sourceFiles_8.length; _i++) {
+                var sourceFile = sourceFiles_8[_i];
+                _loop_6(sourceFile);
+            }
+            rawItems.sort(compareNavigateToItems);
+            if (maxResultCount !== undefined) {
+                rawItems = rawItems.slice(0, maxResultCount);
+            }
+            return rawItems.map(createNavigateToItem);
+        }
+        NavigateTo.getNavigateToItems = getNavigateToItems;
+        function getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, fileName, rawItems) {
+            // First do a quick check to see if the name of the declaration matches the
+            // last portion of the (possibly) dotted name they're searching for.
+            var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name);
+            if (!matches) {
+                return; // continue to next named declarations
+            }
+            for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) {
+                var declaration = declarations_11[_i];
+                if (!shouldKeepItem(declaration, checker)) {
+                    continue;
+                }
+                // It was a match!  If the pattern has dots in it, then also see if the
+                // declaration container matches as well.
+                var containerMatches = matches;
+                if (patternMatcher.patternContainsDots) {
+                    containerMatches = patternMatcher.getMatches(getContainers(declaration), name);
+                    if (!containerMatches) {
+                        continue;
+                    }
+                }
+                var matchKind = bestMatchKind(containerMatches);
+                var isCaseSensitive = allMatchesAreCaseSensitive(containerMatches);
+                rawItems.push({ name: name, fileName: fileName, matchKind: matchKind, isCaseSensitive: isCaseSensitive, declaration: declaration });
+            }
+        }
+        function shouldKeepItem(declaration, checker) {
+            switch (declaration.kind) {
+                case 239 /* ImportClause */:
+                case 242 /* ImportSpecifier */:
+                case 237 /* ImportEqualsDeclaration */:
+                    var importer = checker.getSymbolAtLocation(declaration.name);
+                    var imported = checker.getAliasedSymbol(importer);
+                    return importer.escapedName !== imported.escapedName;
+                default:
+                    return true;
+            }
+        }
+        function allMatchesAreCaseSensitive(matches) {
+            ts.Debug.assert(matches.length > 0);
+            // This is a case sensitive match, only if all the submatches were case sensitive.
+            for (var _i = 0, matches_2 = matches; _i < matches_2.length; _i++) {
+                var match = matches_2[_i];
+                if (!match.isCaseSensitive) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        function tryAddSingleDeclarationName(declaration, containers) {
+            if (declaration) {
+                var name = ts.getNameOfDeclaration(declaration);
+                if (name) {
+                    var text = ts.getTextOfIdentifierOrLiteral(name);
+                    if (text !== undefined) {
+                        containers.unshift(text);
+                    }
+                    else if (name.kind === 144 /* ComputedPropertyName */) {
+                        return tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ true);
+                    }
+                    else {
+                        // Don't know how to add this.
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        // Only added the names of computed properties if they're simple dotted expressions, like:
+        //
+        //      [X.Y.Z]() { }
+        function tryAddComputedPropertyName(expression, containers, includeLastPortion) {
+            var text = ts.getTextOfIdentifierOrLiteral(expression);
+            if (text !== undefined) {
+                if (includeLastPortion) {
+                    containers.unshift(text);
+                }
+                return true;
+            }
+            if (expression.kind === 179 /* PropertyAccessExpression */) {
+                var propertyAccess = expression;
+                if (includeLastPortion) {
+                    containers.unshift(propertyAccess.name.text);
+                }
+                return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true);
+            }
+            return false;
+        }
+        function getContainers(declaration) {
+            var containers = [];
+            // First, if we started with a computed property name, then add all but the last
+            // portion into the container array.
+            var name = ts.getNameOfDeclaration(declaration);
+            if (name.kind === 144 /* ComputedPropertyName */) {
+                if (!tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) {
+                    return undefined;
+                }
+            }
+            // Now, walk up our containers, adding all their names to the container array.
+            declaration = ts.getContainerNode(declaration);
+            while (declaration) {
+                if (!tryAddSingleDeclarationName(declaration, containers)) {
+                    return undefined;
+                }
+                declaration = ts.getContainerNode(declaration);
+            }
+            return containers;
+        }
+        function bestMatchKind(matches) {
+            ts.Debug.assert(matches.length > 0);
+            var bestMatchKind = ts.PatternMatchKind.camelCase;
+            for (var _i = 0, matches_3 = matches; _i < matches_3.length; _i++) {
+                var match = matches_3[_i];
+                var kind = match.kind;
+                if (kind < bestMatchKind) {
+                    bestMatchKind = kind;
+                }
+            }
+            return bestMatchKind;
+        }
+        function compareNavigateToItems(i1, i2) {
+            // TODO(cyrusn): get the gamut of comparisons that VS already uses here.
+            // Right now we just sort by kind first, and then by name of the item.
+            // We first sort case insensitively.  So "Aaa" will come before "bar".
+            // Then we sort case sensitively, so "aaa" will come before "Aaa".
+            return i1.matchKind - i2.matchKind ||
+                ts.compareStringsCaseInsensitive(i1.name, i2.name) ||
+                ts.compareStrings(i1.name, i2.name);
+        }
+        function createNavigateToItem(rawItem) {
+            var declaration = rawItem.declaration;
+            var container = ts.getContainerNode(declaration);
+            var containerName = container && ts.getNameOfDeclaration(container);
+            return {
+                name: rawItem.name,
+                kind: ts.getNodeKind(declaration),
+                kindModifiers: ts.getNodeModifiers(declaration),
+                matchKind: ts.PatternMatchKind[rawItem.matchKind],
+                isCaseSensitive: rawItem.isCaseSensitive,
+                fileName: rawItem.fileName,
+                textSpan: ts.createTextSpanFromNode(declaration),
+                // TODO(jfreeman): What should be the containerName when the container has a computed name?
+                containerName: containerName ? containerName.text : "",
+                containerKind: containerName ? ts.getNodeKind(container) : "" /* unknown */
+            };
+        }
+    })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {}));
+})(ts || (ts = {}));
+/// <reference path='services.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var NavigationBar;
+    (function (NavigationBar) {
+        /**
+         * Matches all whitespace characters in a string. Eg:
+         *
+         * "app.
+         *
+         * onactivated"
+         *
+         * matches because of the newline, whereas
+         *
+         * "app.onactivated"
+         *
+         * does not match.
+         */
+        var whiteSpaceRegex = /\s+/g;
+        // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
+        var curCancellationToken;
+        var curSourceFile;
+        /**
+         * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
+         * `parent` is the current parent and is *not* stored in parentsStack.
+         * `startNode` sets a new parent and `endNode` returns to the previous parent.
+         */
+        var parentsStack = [];
+        var parent;
+        // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
+        var emptyChildItemArray = [];
+        function getNavigationBarItems(sourceFile, cancellationToken) {
+            curCancellationToken = cancellationToken;
+            curSourceFile = sourceFile;
+            try {
+                return ts.map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
+            }
+            finally {
+                reset();
+            }
+        }
+        NavigationBar.getNavigationBarItems = getNavigationBarItems;
+        function getNavigationTree(sourceFile, cancellationToken) {
+            curCancellationToken = cancellationToken;
+            curSourceFile = sourceFile;
+            try {
+                return convertToTree(rootNavigationBarNode(sourceFile));
+            }
+            finally {
+                reset();
+            }
+        }
+        NavigationBar.getNavigationTree = getNavigationTree;
+        function reset() {
+            curSourceFile = undefined;
+            curCancellationToken = undefined;
+            parentsStack = [];
+            parent = undefined;
+            emptyChildItemArray = [];
+        }
+        function nodeText(node) {
+            return node.getText(curSourceFile);
+        }
+        function navigationBarNodeKind(n) {
+            return n.node.kind;
+        }
+        function pushChild(parent, child) {
+            if (parent.children) {
+                parent.children.push(child);
+            }
+            else {
+                parent.children = [child];
+            }
+        }
+        function rootNavigationBarNode(sourceFile) {
+            ts.Debug.assert(!parentsStack.length);
+            var root = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
+            parent = root;
+            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
+                var statement = _a[_i];
+                addChildrenRecursively(statement);
+            }
+            endNode();
+            ts.Debug.assert(!parent && !parentsStack.length);
+            return root;
+        }
+        function addLeafNode(node) {
+            pushChild(parent, emptyNavigationBarNode(node));
+        }
+        function emptyNavigationBarNode(node) {
+            return {
+                node: node,
+                additionalNodes: undefined,
+                parent: parent,
+                children: undefined,
+                indent: parent.indent + 1
+            };
+        }
+        /**
+         * Add a new level of NavigationBarNodes.
+         * This pushes to the stack, so you must call `endNode` when you are done adding to this node.
+         */
+        function startNode(node) {
+            var navNode = emptyNavigationBarNode(node);
+            pushChild(parent, navNode);
+            // Save the old parent
+            parentsStack.push(parent);
+            parent = navNode;
+        }
+        /** Call after calling `startNode` and adding children to it. */
+        function endNode() {
+            if (parent.children) {
+                mergeChildren(parent.children);
+                sortChildren(parent.children);
+            }
+            parent = parentsStack.pop();
+        }
+        function addNodeWithRecursiveChild(node, child) {
+            startNode(node);
+            addChildrenRecursively(child);
+            endNode();
+        }
+        /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
+        function addChildrenRecursively(node) {
+            curCancellationToken.throwIfCancellationRequested();
+            if (!node || ts.isToken(node)) {
+                return;
+            }
+            switch (node.kind) {
+                case 152 /* Constructor */:
+                    // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it.
+                    var ctr = node;
+                    addNodeWithRecursiveChild(ctr, ctr.body);
+                    // Parameter properties are children of the class, not the constructor.
+                    for (var _i = 0, _a = ctr.parameters; _i < _a.length; _i++) {
+                        var param = _a[_i];
+                        if (ts.isParameterPropertyDeclaration(param)) {
+                            addLeafNode(param);
+                        }
+                    }
+                    break;
+                case 151 /* MethodDeclaration */:
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 150 /* MethodSignature */:
+                    if (!ts.hasDynamicName(node)) {
+                        addNodeWithRecursiveChild(node, node.body);
+                    }
+                    break;
+                case 149 /* PropertyDeclaration */:
+                case 148 /* PropertySignature */:
+                    if (!ts.hasDynamicName(node)) {
+                        addLeafNode(node);
+                    }
+                    break;
+                case 239 /* ImportClause */:
+                    var importClause = node;
+                    // Handle default import case e.g.:
+                    //    import d from "mod";
+                    if (importClause.name) {
+                        addLeafNode(importClause);
+                    }
+                    // Handle named bindings in imports e.g.:
+                    //    import * as NS from "mod";
+                    //    import {a, b as B} from "mod";
+                    var namedBindings = importClause.namedBindings;
+                    if (namedBindings) {
+                        if (namedBindings.kind === 240 /* NamespaceImport */) {
+                            addLeafNode(namedBindings);
+                        }
+                        else {
+                            for (var _b = 0, _c = namedBindings.elements; _b < _c.length; _b++) {
+                                var element = _c[_b];
+                                addLeafNode(element);
+                            }
+                        }
+                    }
+                    break;
+                case 176 /* BindingElement */:
+                case 226 /* VariableDeclaration */:
+                    var _d = node, name = _d.name, initializer = _d.initializer;
+                    if (ts.isBindingPattern(name)) {
+                        addChildrenRecursively(name);
+                    }
+                    else if (initializer && isFunctionOrClassExpression(initializer)) {
+                        if (initializer.name) {
+                            // Don't add a node for the VariableDeclaration, just for the initializer.
+                            addChildrenRecursively(initializer);
+                        }
+                        else {
+                            // Add a node for the VariableDeclaration, but not for the initializer.
+                            startNode(node);
+                            ts.forEachChild(initializer, addChildrenRecursively);
+                            endNode();
+                        }
+                    }
+                    else {
+                        addNodeWithRecursiveChild(node, initializer);
+                    }
+                    break;
+                case 187 /* ArrowFunction */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                    addNodeWithRecursiveChild(node, node.body);
+                    break;
+                case 232 /* EnumDeclaration */:
+                    startNode(node);
+                    for (var _e = 0, _f = node.members; _e < _f.length; _e++) {
+                        var member = _f[_e];
+                        if (!isComputedProperty(member)) {
+                            addLeafNode(member);
+                        }
+                    }
+                    endNode();
+                    break;
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                case 230 /* InterfaceDeclaration */:
+                    startNode(node);
+                    for (var _g = 0, _h = node.members; _g < _h.length; _g++) {
+                        var member = _h[_g];
+                        addChildrenRecursively(member);
+                    }
+                    endNode();
+                    break;
+                case 233 /* ModuleDeclaration */:
+                    addNodeWithRecursiveChild(node, getInteriorModule(node).body);
+                    break;
+                case 246 /* ExportSpecifier */:
+                case 237 /* ImportEqualsDeclaration */:
+                case 157 /* IndexSignature */:
+                case 155 /* CallSignature */:
+                case 156 /* ConstructSignature */:
+                case 231 /* TypeAliasDeclaration */:
+                    addLeafNode(node);
+                    break;
+                default:
+                    if (ts.hasJSDocNodes(node)) {
+                        ts.forEach(node.jsDoc, function (jsDoc) {
+                            ts.forEach(jsDoc.tags, function (tag) {
+                                if (tag.kind === 283 /* JSDocTypedefTag */) {
+                                    addLeafNode(tag);
+                                }
+                            });
+                        });
+                    }
+                    ts.forEachChild(node, addChildrenRecursively);
+            }
+        }
+        /** Merge declarations of the same kind. */
+        function mergeChildren(children) {
+            var nameToItems = ts.createMap();
+            ts.filterMutate(children, function (child) {
+                var declName = ts.getNameOfDeclaration(child.node);
+                var name = declName && nodeText(declName);
+                if (!name) {
+                    // Anonymous items are never merged.
+                    return true;
+                }
+                var itemsWithSameName = nameToItems.get(name);
+                if (!itemsWithSameName) {
+                    nameToItems.set(name, child);
+                    return true;
+                }
+                if (itemsWithSameName instanceof Array) {
+                    for (var _i = 0, itemsWithSameName_1 = itemsWithSameName; _i < itemsWithSameName_1.length; _i++) {
+                        var itemWithSameName = itemsWithSameName_1[_i];
+                        if (tryMerge(itemWithSameName, child)) {
+                            return false;
+                        }
+                    }
+                    itemsWithSameName.push(child);
+                    return true;
+                }
+                else {
+                    var itemWithSameName = itemsWithSameName;
+                    if (tryMerge(itemWithSameName, child)) {
+                        return false;
+                    }
+                    nameToItems.set(name, [itemWithSameName, child]);
+                    return true;
+                }
+                function tryMerge(a, b) {
+                    if (shouldReallyMerge(a.node, b.node)) {
+                        merge(a, b);
+                        return true;
+                    }
+                    return false;
+                }
+            });
+            /** a and b have the same name, but they may not be mergeable. */
+            function shouldReallyMerge(a, b) {
+                return a.kind === b.kind && (a.kind !== 233 /* ModuleDeclaration */ || areSameModule(a, b));
+                // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
+                // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
+                function areSameModule(a, b) {
+                    if (a.body.kind !== b.body.kind) {
+                        return false;
+                    }
+                    if (a.body.kind !== 233 /* ModuleDeclaration */) {
+                        return true;
+                    }
+                    return areSameModule(a.body, b.body);
+                }
+            }
+            /** Merge source into target. Source should be thrown away after this is called. */
+            function merge(target, source) {
+                target.additionalNodes = target.additionalNodes || [];
+                target.additionalNodes.push(source.node);
+                if (source.additionalNodes) {
+                    (_a = target.additionalNodes).push.apply(_a, source.additionalNodes);
+                }
+                target.children = ts.concatenate(target.children, source.children);
+                if (target.children) {
+                    mergeChildren(target.children);
+                    sortChildren(target.children);
+                }
+                var _a;
+            }
+        }
+        /** Recursively ensure that each NavNode's children are in sorted order. */
+        function sortChildren(children) {
+            children.sort(compareChildren);
+        }
+        function compareChildren(child1, child2) {
+            var name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
+            if (name1 && name2) {
+                var cmp = ts.compareStringsCaseInsensitive(name1, name2);
+                return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
+            }
+            else {
+                return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
+            }
+        }
+        /**
+         * This differs from getItemName because this is just used for sorting.
+         * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.
+         * So `new()` can still come before an `aardvark` method.
+         */
+        function tryGetName(node) {
+            if (node.kind === 233 /* ModuleDeclaration */) {
+                return getModuleName(node);
+            }
+            var declName = ts.getNameOfDeclaration(node);
+            if (declName) {
+                return ts.unescapeLeadingUnderscores(ts.getPropertyNameForPropertyNameNode(declName));
+            }
+            switch (node.kind) {
+                case 186 /* FunctionExpression */:
+                case 187 /* ArrowFunction */:
+                case 199 /* ClassExpression */:
+                    return getFunctionOrClassName(node);
+                case 283 /* JSDocTypedefTag */:
+                    return getJSDocTypedefTagName(node);
+                default:
+                    return undefined;
+            }
+        }
+        function getItemName(node) {
+            if (node.kind === 233 /* ModuleDeclaration */) {
+                return getModuleName(node);
+            }
+            var name = ts.getNameOfDeclaration(node);
+            if (name) {
+                var text = nodeText(name);
+                if (text.length > 0) {
+                    return text;
+                }
+            }
+            switch (node.kind) {
+                case 265 /* SourceFile */:
+                    var sourceFile = node;
+                    return ts.isExternalModule(sourceFile)
+                        ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\""
+                        : "<global>";
+                case 187 /* ArrowFunction */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 229 /* ClassDeclaration */:
+                case 199 /* ClassExpression */:
+                    if (ts.getModifierFlags(node) & 512 /* Default */) {
+                        return "default";
+                    }
+                    // We may get a string with newlines or other whitespace in the case of an object dereference
+                    // (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the
+                    // navigation bar.
+                    return getFunctionOrClassName(node);
+                case 152 /* Constructor */:
+                    return "constructor";
+                case 156 /* ConstructSignature */:
+                    return "new()";
+                case 155 /* CallSignature */:
+                    return "()";
+                case 157 /* IndexSignature */:
+                    return "[]";
+                case 283 /* JSDocTypedefTag */:
+                    return getJSDocTypedefTagName(node);
+                default:
+                    return "<unknown>";
+            }
+        }
+        function getJSDocTypedefTagName(node) {
+            if (node.name) {
+                return node.name.text;
+            }
+            else {
+                var parentNode = node.parent && node.parent.parent;
+                if (parentNode && parentNode.kind === 208 /* VariableStatement */) {
+                    if (parentNode.declarationList.declarations.length > 0) {
+                        var nameIdentifier = parentNode.declarationList.declarations[0].name;
+                        if (nameIdentifier.kind === 71 /* Identifier */) {
+                            return nameIdentifier.text;
+                        }
+                    }
+                }
+                return "<typedef>";
+            }
+        }
+        /** Flattens the NavNode tree to a list, keeping only the top-level items. */
+        function topLevelItems(root) {
+            var topLevel = [];
+            function recur(item) {
+                if (isTopLevel(item)) {
+                    topLevel.push(item);
+                    if (item.children) {
+                        for (var _i = 0, _a = item.children; _i < _a.length; _i++) {
+                            var child = _a[_i];
+                            recur(child);
+                        }
+                    }
+                }
+            }
+            recur(root);
+            return topLevel;
+            function isTopLevel(item) {
+                switch (navigationBarNodeKind(item)) {
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 232 /* EnumDeclaration */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 233 /* ModuleDeclaration */:
+                    case 265 /* SourceFile */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 283 /* JSDocTypedefTag */:
+                        return true;
+                    case 152 /* Constructor */:
+                    case 151 /* MethodDeclaration */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 226 /* VariableDeclaration */:
+                        return hasSomeImportantChild(item);
+                    case 187 /* ArrowFunction */:
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                        return isTopLevelFunctionDeclaration(item);
+                    default:
+                        return false;
+                }
+                function isTopLevelFunctionDeclaration(item) {
+                    if (!item.node.body) {
+                        return false;
+                    }
+                    switch (navigationBarNodeKind(item.parent)) {
+                        case 234 /* ModuleBlock */:
+                        case 265 /* SourceFile */:
+                        case 151 /* MethodDeclaration */:
+                        case 152 /* Constructor */:
+                            return true;
+                        default:
+                            return hasSomeImportantChild(item);
+                    }
+                }
+                function hasSomeImportantChild(item) {
+                    return ts.forEach(item.children, function (child) {
+                        var childKind = navigationBarNodeKind(child);
+                        return childKind !== 226 /* VariableDeclaration */ && childKind !== 176 /* BindingElement */;
+                    });
+                }
+            }
+        }
+        function convertToTree(n) {
+            return {
+                text: getItemName(n.node),
+                kind: ts.getNodeKind(n.node),
+                kindModifiers: getModifiers(n.node),
+                spans: getSpans(n),
+                childItems: ts.map(n.children, convertToTree)
+            };
+        }
+        function convertToTopLevelItem(n) {
+            return {
+                text: getItemName(n.node),
+                kind: ts.getNodeKind(n.node),
+                kindModifiers: getModifiers(n.node),
+                spans: getSpans(n),
+                childItems: ts.map(n.children, convertToChildItem) || emptyChildItemArray,
+                indent: n.indent,
+                bolded: false,
+                grayed: false
+            };
+            function convertToChildItem(n) {
+                return {
+                    text: getItemName(n.node),
+                    kind: ts.getNodeKind(n.node),
+                    kindModifiers: ts.getNodeModifiers(n.node),
+                    spans: getSpans(n),
+                    childItems: emptyChildItemArray,
+                    indent: 0,
+                    bolded: false,
+                    grayed: false
+                };
+            }
+        }
+        function getSpans(n) {
+            var spans = [getNodeSpan(n.node)];
+            if (n.additionalNodes) {
+                for (var _i = 0, _a = n.additionalNodes; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    spans.push(getNodeSpan(node));
+                }
+            }
+            return spans;
+        }
+        function getModuleName(moduleDeclaration) {
+            // We want to maintain quotation marks.
+            if (ts.isAmbientModule(moduleDeclaration)) {
+                return ts.getTextOfNode(moduleDeclaration.name);
+            }
+            // Otherwise, we need to aggregate each identifier to build up the qualified name.
+            var result = [];
+            result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
+            while (moduleDeclaration.body && moduleDeclaration.body.kind === 233 /* ModuleDeclaration */) {
+                moduleDeclaration = moduleDeclaration.body;
+                result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
+            }
+            return result.join(".");
+        }
+        /**
+         * For 'module A.B.C', we want to get the node for 'C'.
+         * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again.
+         */
+        function getInteriorModule(decl) {
+            return decl.body.kind === 233 /* ModuleDeclaration */ ? getInteriorModule(decl.body) : decl;
+        }
+        function isComputedProperty(member) {
+            return !member.name || member.name.kind === 144 /* ComputedPropertyName */;
+        }
+        function getNodeSpan(node) {
+            return node.kind === 265 /* SourceFile */
+                ? ts.createTextSpanFromBounds(node.getFullStart(), node.getEnd())
+                : ts.createTextSpanFromNode(node, curSourceFile);
+        }
+        function getModifiers(node) {
+            if (node.parent && node.parent.kind === 226 /* VariableDeclaration */) {
+                node = node.parent;
+            }
+            return ts.getNodeModifiers(node);
+        }
+        function getFunctionOrClassName(node) {
+            if (node.name && ts.getFullWidth(node.name) > 0) {
+                return ts.declarationNameToString(node.name);
+            }
+            else if (node.parent.kind === 226 /* VariableDeclaration */) {
+                return ts.declarationNameToString(node.parent.name);
+            }
+            else if (node.parent.kind === 194 /* BinaryExpression */ &&
+                node.parent.operatorToken.kind === 58 /* EqualsToken */) {
+                return nodeText(node.parent.left).replace(whiteSpaceRegex, "");
+            }
+            else if (node.parent.kind === 261 /* PropertyAssignment */ && node.parent.name) {
+                return nodeText(node.parent.name);
+            }
+            else if (ts.getModifierFlags(node) & 512 /* Default */) {
+                return "default";
+            }
+            else {
+                return ts.isClassLike(node) ? "<class>" : "<function>";
+            }
+        }
+        function isFunctionOrClassExpression(node) {
+            switch (node.kind) {
+                case 187 /* ArrowFunction */:
+                case 186 /* FunctionExpression */:
+                case 199 /* ClassExpression */:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var OutliningElementsCollector;
+    (function (OutliningElementsCollector) {
+        var collapseText = "...";
+        var maxDepth = 40;
+        var defaultLabel = "#region";
+        var regionMatch = new RegExp("^\\s*//\\s*#(end)?region(?:\\s+(.*))?$");
+        function collectElements(sourceFile, cancellationToken) {
+            var elements = [];
+            var depth = 0;
+            var regions = [];
+            walk(sourceFile);
+            gatherRegions();
+            return elements.sort(function (span1, span2) { return span1.textSpan.start - span2.textSpan.start; });
+            /** If useFullStart is true, then the collapsing span includes leading whitespace, including linebreaks. */
+            function addOutliningSpan(hintSpanNode, startElement, endElement, autoCollapse, useFullStart) {
+                if (hintSpanNode && startElement && endElement) {
+                    var span_13 = {
+                        textSpan: ts.createTextSpanFromBounds(useFullStart ? startElement.getFullStart() : startElement.getStart(), endElement.getEnd()),
+                        hintSpan: ts.createTextSpanFromNode(hintSpanNode, sourceFile),
+                        bannerText: collapseText,
+                        autoCollapse: autoCollapse,
+                    };
+                    elements.push(span_13);
+                }
+            }
+            function addOutliningSpanComments(commentSpan, autoCollapse) {
+                if (commentSpan) {
+                    var span_14 = {
+                        textSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
+                        hintSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
+                        bannerText: collapseText,
+                        autoCollapse: autoCollapse,
+                    };
+                    elements.push(span_14);
+                }
+            }
+            function addOutliningForLeadingCommentsForNode(n) {
+                var comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
+                if (comments) {
+                    var firstSingleLineCommentStart = -1;
+                    var lastSingleLineCommentEnd = -1;
+                    var isFirstSingleLineComment = true;
+                    var singleLineCommentCount = 0;
+                    for (var _i = 0, comments_3 = comments; _i < comments_3.length; _i++) {
+                        var currentComment = comments_3[_i];
+                        cancellationToken.throwIfCancellationRequested();
+                        // For single line comments, combine consecutive ones (2 or more) into
+                        // a single span from the start of the first till the end of the last
+                        if (currentComment.kind === 2 /* SingleLineCommentTrivia */) {
+                            if (isFirstSingleLineComment) {
+                                firstSingleLineCommentStart = currentComment.pos;
+                            }
+                            isFirstSingleLineComment = false;
+                            lastSingleLineCommentEnd = currentComment.end;
+                            singleLineCommentCount++;
+                        }
+                        else if (currentComment.kind === 3 /* MultiLineCommentTrivia */) {
+                            combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
+                            addOutliningSpanComments(currentComment, /*autoCollapse*/ false);
+                            singleLineCommentCount = 0;
+                            lastSingleLineCommentEnd = -1;
+                            isFirstSingleLineComment = true;
+                        }
+                    }
+                    combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
+                }
+            }
+            function combineAndAddMultipleSingleLineComments(count, start, end) {
+                // Only outline spans of two or more consecutive single line comments
+                if (count > 1) {
+                    var multipleSingleLineComments = {
+                        kind: 2 /* SingleLineCommentTrivia */,
+                        pos: start,
+                        end: end,
+                    };
+                    addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
+                }
+            }
+            function autoCollapse(node) {
+                return ts.isFunctionBlock(node) && node.parent.kind !== 187 /* ArrowFunction */;
+            }
+            function gatherRegions() {
+                var lineStarts = sourceFile.getLineStarts();
+                for (var i = 0; i < lineStarts.length; i++) {
+                    var currentLineStart = lineStarts[i];
+                    var lineEnd = lineStarts[i + 1] - 1 || sourceFile.getEnd();
+                    var comment = sourceFile.text.substring(currentLineStart, lineEnd);
+                    var result = comment.match(regionMatch);
+                    if (result && !ts.isInComment(sourceFile, currentLineStart)) {
+                        if (!result[1]) {
+                            var start = sourceFile.getFullText().indexOf("//", currentLineStart);
+                            var textSpan = ts.createTextSpanFromBounds(start, lineEnd);
+                            var region = {
+                                textSpan: textSpan,
+                                hintSpan: textSpan,
+                                bannerText: result[2] || defaultLabel,
+                                autoCollapse: false
+                            };
+                            regions.push(region);
+                        }
+                        else {
+                            var region = regions.pop();
+                            if (region) {
+                                region.textSpan.length = lineEnd - region.textSpan.start;
+                                region.hintSpan.length = lineEnd - region.textSpan.start;
+                                elements.push(region);
+                            }
+                        }
+                    }
+                }
+            }
+            function walk(n) {
+                cancellationToken.throwIfCancellationRequested();
+                if (depth > maxDepth) {
+                    return;
+                }
+                if (ts.isDeclaration(n)) {
+                    addOutliningForLeadingCommentsForNode(n);
+                }
+                switch (n.kind) {
+                    case 207 /* Block */:
+                        if (!ts.isFunctionBlock(n)) {
+                            var parent = n.parent;
+                            var openBrace_1 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
+                            var closeBrace_1 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
+                            // Check if the block is standalone, or 'attached' to some parent statement.
+                            // If the latter, we want to collapse the block, but consider its hint span
+                            // to be the entire span of the parent.
+                            if (parent.kind === 212 /* DoStatement */ ||
+                                parent.kind === 215 /* ForInStatement */ ||
+                                parent.kind === 216 /* ForOfStatement */ ||
+                                parent.kind === 214 /* ForStatement */ ||
+                                parent.kind === 211 /* IfStatement */ ||
+                                parent.kind === 213 /* WhileStatement */ ||
+                                parent.kind === 220 /* WithStatement */ ||
+                                parent.kind === 260 /* CatchClause */) {
+                                addOutliningSpan(parent, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
+                                break;
+                            }
+                            if (parent.kind === 224 /* TryStatement */) {
+                                // Could be the try-block, or the finally-block.
+                                var tryStatement = parent;
+                                if (tryStatement.tryBlock === n) {
+                                    addOutliningSpan(parent, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
+                                    break;
+                                }
+                                else if (tryStatement.finallyBlock === n) {
+                                    var finallyKeyword = ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile);
+                                    if (finallyKeyword) {
+                                        addOutliningSpan(finallyKeyword, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
+                                        break;
+                                    }
+                                }
+                                // fall through.
+                            }
+                            // Block was a standalone block.  In this case we want to only collapse
+                            // the span of the block, independent of any parent span.
+                            var span_15 = ts.createTextSpanFromNode(n);
+                            elements.push({
+                                textSpan: span_15,
+                                hintSpan: span_15,
+                                bannerText: collapseText,
+                                autoCollapse: autoCollapse(n)
+                            });
+                            break;
+                        }
+                    // falls through
+                    case 234 /* ModuleBlock */: {
+                        var openBrace_2 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
+                        var closeBrace_2 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
+                        addOutliningSpan(n.parent, openBrace_2, closeBrace_2, autoCollapse(n), /*useFullStart*/ true);
+                        break;
+                    }
+                    case 229 /* ClassDeclaration */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 235 /* CaseBlock */: {
+                        var openBrace_3 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
+                        var closeBrace_3 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
+                        addOutliningSpan(n, openBrace_3, closeBrace_3, autoCollapse(n), /*useFullStart*/ true);
+                        break;
+                    }
+                    // If the block has no leading keywords and is inside an array literal,
+                    // we only want to collapse the span of the block.
+                    // Otherwise, the collapsed section will include the end of the previous line.
+                    case 178 /* ObjectLiteralExpression */:
+                        var openBrace = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
+                        var closeBrace = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
+                        addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n), /*useFullStart*/ !ts.isArrayLiteralExpression(n.parent));
+                        break;
+                    case 177 /* ArrayLiteralExpression */:
+                        var openBracket = ts.findChildOfKind(n, 21 /* OpenBracketToken */, sourceFile);
+                        var closeBracket = ts.findChildOfKind(n, 22 /* CloseBracketToken */, sourceFile);
+                        addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n), /*useFullStart*/ !ts.isArrayLiteralExpression(n.parent));
+                        break;
+                }
+                depth++;
+                ts.forEachChild(n, walk);
+                depth--;
+            }
+        }
+        OutliningElementsCollector.collectElements = collectElements;
+    })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    // Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
+    var PatternMatchKind;
+    (function (PatternMatchKind) {
+        PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact";
+        PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix";
+        PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring";
+        PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase";
+    })(PatternMatchKind = ts.PatternMatchKind || (ts.PatternMatchKind = {}));
+    function createPatternMatch(kind, punctuationStripped, isCaseSensitive, camelCaseWeight) {
+        return {
+            kind: kind,
+            punctuationStripped: punctuationStripped,
+            isCaseSensitive: isCaseSensitive,
+            camelCaseWeight: camelCaseWeight
+        };
+    }
+    function createPatternMatcher(pattern) {
+        // We'll often see the same candidate string many times when searching (For example, when
+        // we see the name of a module that is used everywhere, or the name of an overload).  As
+        // such, we cache the information we compute about the candidate for the life of this
+        // pattern matcher so we don't have to compute it multiple times.
+        var stringToWordSpans = ts.createMap();
+        pattern = pattern.trim();
+        var dotSeparatedSegments = pattern.split(".").map(function (p) { return createSegment(p.trim()); });
+        var invalidPattern = dotSeparatedSegments.length === 0 || ts.forEach(dotSeparatedSegments, segmentIsInvalid);
+        return {
+            getMatches: getMatches,
+            getMatchesForLastSegmentOfPattern: getMatchesForLastSegmentOfPattern,
+            patternContainsDots: dotSeparatedSegments.length > 1
+        };
+        // Quick checks so we can bail out when asked to match a candidate.
+        function skipMatch(candidate) {
+            return invalidPattern || !candidate;
+        }
+        function getMatchesForLastSegmentOfPattern(candidate) {
+            if (skipMatch(candidate)) {
+                return undefined;
+            }
+            return matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments));
+        }
+        function getMatches(candidateContainers, candidate) {
+            if (skipMatch(candidate)) {
+                return undefined;
+            }
+            // First, check that the last part of the dot separated pattern matches the name of the
+            // candidate.  If not, then there's no point in proceeding and doing the more
+            // expensive work.
+            var candidateMatch = matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments));
+            if (!candidateMatch) {
+                return undefined;
+            }
+            candidateContainers = candidateContainers || [];
+            // -1 because the last part was checked against the name, and only the rest
+            // of the parts are checked against the container.
+            if (dotSeparatedSegments.length - 1 > candidateContainers.length) {
+                // There weren't enough container parts to match against the pattern parts.
+                // So this definitely doesn't match.
+                return undefined;
+            }
+            // So far so good.  Now break up the container for the candidate and check if all
+            // the dotted parts match up correctly.
+            var totalMatch = candidateMatch;
+            for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) {
+                var segment = dotSeparatedSegments[i];
+                var containerName = candidateContainers[j];
+                var containerMatch = matchSegment(containerName, segment);
+                if (!containerMatch) {
+                    // This container didn't match the pattern piece.  So there's no match at all.
+                    return undefined;
+                }
+                ts.addRange(totalMatch, containerMatch);
+            }
+            // Success, this symbol's full name matched against the dotted name the user was asking
+            // about.
+            return totalMatch;
+        }
+        function getWordSpans(word) {
+            var spans = stringToWordSpans.get(word);
+            if (!spans) {
+                stringToWordSpans.set(word, spans = breakIntoWordSpans(word));
+            }
+            return spans;
+        }
+        function matchTextChunk(candidate, chunk, punctuationStripped) {
+            var index = indexOfIgnoringCase(candidate, chunk.textLowerCase);
+            if (index === 0) {
+                if (chunk.text.length === candidate.length) {
+                    // a) Check if the part matches the candidate entirely, in an case insensitive or
+                    //    sensitive manner.  If it does, return that there was an exact match.
+                    return createPatternMatch(PatternMatchKind.exact, punctuationStripped, /*isCaseSensitive:*/ candidate === chunk.text);
+                }
+                else {
+                    // b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive
+                    //    manner.  If it does, return that there was a prefix match.
+                    return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text));
+                }
+            }
+            var isLowercase = chunk.isLowerCase;
+            if (isLowercase) {
+                if (index > 0) {
+                    // c) If the part is entirely lowercase, then check if it is contained anywhere in the
+                    //    candidate in a case insensitive manner.  If so, return that there was a substring
+                    //    match.
+                    //
+                    //    Note: We only have a substring match if the lowercase part is prefix match of some
+                    //    word part. That way we don't match something like 'Class' when the user types 'a'.
+                    //    But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
+                    var wordSpans = getWordSpans(candidate);
+                    for (var _i = 0, wordSpans_1 = wordSpans; _i < wordSpans_1.length; _i++) {
+                        var span_16 = wordSpans_1[_i];
+                        if (partStartsWith(candidate, span_16, chunk.text, /*ignoreCase:*/ true)) {
+                            return createPatternMatch(PatternMatchKind.substring, punctuationStripped, 
+                            /*isCaseSensitive:*/ partStartsWith(candidate, span_16, chunk.text, /*ignoreCase:*/ false));
+                        }
+                    }
+                }
+            }
+            else {
+                // d) If the part was not entirely lowercase, then check if it is contained in the
+                //    candidate in a case *sensitive* manner. If so, return that there was a substring
+                //    match.
+                if (candidate.indexOf(chunk.text) > 0) {
+                    return createPatternMatch(PatternMatchKind.substring, punctuationStripped, /*isCaseSensitive:*/ true);
+                }
+            }
+            if (!isLowercase) {
+                // e) If the part was not entirely lowercase, then attempt a camel cased match as well.
+                if (chunk.characterSpans.length > 0) {
+                    var candidateParts = getWordSpans(candidate);
+                    var camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false);
+                    if (camelCaseWeight !== undefined) {
+                        return createPatternMatch(PatternMatchKind.camelCase, punctuationStripped, /*isCaseSensitive:*/ true, /*camelCaseWeight:*/ camelCaseWeight);
+                    }
+                    camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ true);
+                    if (camelCaseWeight !== undefined) {
+                        return createPatternMatch(PatternMatchKind.camelCase, punctuationStripped, /*isCaseSensitive:*/ false, /*camelCaseWeight:*/ camelCaseWeight);
+                    }
+                }
+            }
+            if (isLowercase) {
+                // f) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
+                // We could check every character boundary start of the candidate for the pattern. However, that's
+                // an m * n operation in the wost case. Instead, find the first instance of the pattern
+                // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
+                // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
+                // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
+                if (chunk.text.length < candidate.length) {
+                    if (index > 0 && isUpperCaseLetter(candidate.charCodeAt(index))) {
+                        return createPatternMatch(PatternMatchKind.substring, punctuationStripped, /*isCaseSensitive:*/ false);
+                    }
+                }
+            }
+            return undefined;
+        }
+        function containsSpaceOrAsterisk(text) {
+            for (var i = 0; i < text.length; i++) {
+                var ch = text.charCodeAt(i);
+                if (ch === 32 /* space */ || ch === 42 /* asterisk */) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        function matchSegment(candidate, segment) {
+            // First check if the segment matches as is.  This is also useful if the segment contains
+            // characters we would normally strip when splitting into parts that we also may want to
+            // match in the candidate.  For example if the segment is "@int" and the candidate is
+            // "@int", then that will show up as an exact match here.
+            //
+            // Note: if the segment contains a space or an asterisk then we must assume that it's a
+            // multi-word segment.
+            if (!containsSpaceOrAsterisk(segment.totalTextChunk.text)) {
+                var match = matchTextChunk(candidate, segment.totalTextChunk, /*punctuationStripped:*/ false);
+                if (match) {
+                    return [match];
+                }
+            }
+            // The logic for pattern matching is now as follows:
+            //
+            // 1) Break the segment passed in into words.  Breaking is rather simple and a
+            //    good way to think about it that if gives you all the individual alphanumeric words
+            //    of the pattern.
+            //
+            // 2) For each word try to match the word against the candidate value.
+            //
+            // 3) Matching is as follows:
+            //
+            //   a) Check if the word matches the candidate entirely, in an case insensitive or
+            //    sensitive manner.  If it does, return that there was an exact match.
+            //
+            //   b) Check if the word is a prefix of the candidate, in a case insensitive or
+            //      sensitive manner.  If it does, return that there was a prefix match.
+            //
+            //   c) If the word is entirely lowercase, then check if it is contained anywhere in the
+            //      candidate in a case insensitive manner.  If so, return that there was a substring
+            //      match.
+            //
+            //      Note: We only have a substring match if the lowercase part is prefix match of
+            //      some word part. That way we don't match something like 'Class' when the user
+            //      types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
+            //      'a').
+            //
+            //   d) If the word was not entirely lowercase, then check if it is contained in the
+            //      candidate in a case *sensitive* manner. If so, return that there was a substring
+            //      match.
+            //
+            //   e) If the word was not entirely lowercase, then attempt a camel cased match as
+            //      well.
+            //
+            //   f) The word is all lower case. Is it a case insensitive substring of the candidate starting
+            //      on a part boundary of the candidate?
+            //
+            // Only if all words have some sort of match is the pattern considered matched.
+            var subWordTextChunks = segment.subWordTextChunks;
+            var matches = undefined;
+            for (var _i = 0, subWordTextChunks_1 = subWordTextChunks; _i < subWordTextChunks_1.length; _i++) {
+                var subWordTextChunk = subWordTextChunks_1[_i];
+                // Try to match the candidate with this word
+                var result = matchTextChunk(candidate, subWordTextChunk, /*punctuationStripped:*/ true);
+                if (!result) {
+                    return undefined;
+                }
+                matches = matches || [];
+                matches.push(result);
+            }
+            return matches;
+        }
+        function partStartsWith(candidate, candidateSpan, pattern, ignoreCase, patternSpan) {
+            var patternPartStart = patternSpan ? patternSpan.start : 0;
+            var patternPartLength = patternSpan ? patternSpan.length : pattern.length;
+            if (patternPartLength > candidateSpan.length) {
+                // Pattern part is longer than the candidate part. There can never be a match.
+                return false;
+            }
+            if (ignoreCase) {
+                for (var i = 0; i < patternPartLength; i++) {
+                    var ch1 = pattern.charCodeAt(patternPartStart + i);
+                    var ch2 = candidate.charCodeAt(candidateSpan.start + i);
+                    if (toLowerCase(ch1) !== toLowerCase(ch2)) {
+                        return false;
+                    }
+                }
+            }
+            else {
+                for (var i = 0; i < patternPartLength; i++) {
+                    var ch1 = pattern.charCodeAt(patternPartStart + i);
+                    var ch2 = candidate.charCodeAt(candidateSpan.start + i);
+                    if (ch1 !== ch2) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        function tryCamelCaseMatch(candidate, candidateParts, chunk, ignoreCase) {
+            var chunkCharacterSpans = chunk.characterSpans;
+            // Note: we may have more pattern parts than candidate parts.  This is because multiple
+            // pattern parts may match a candidate part.  For example "SiUI" against "SimpleUI".
+            // We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI.  However, U
+            // and I will both match in UI.
+            var currentCandidate = 0;
+            var currentChunkSpan = 0;
+            var firstMatch = undefined;
+            var contiguous = undefined;
+            while (true) {
+                // Let's consider our termination cases
+                if (currentChunkSpan === chunkCharacterSpans.length) {
+                    // We did match! We shall assign a weight to this
+                    var weight = 0;
+                    // Was this contiguous?
+                    if (contiguous) {
+                        weight += 1;
+                    }
+                    // Did we start at the beginning of the candidate?
+                    if (firstMatch === 0) {
+                        weight += 2;
+                    }
+                    return weight;
+                }
+                else if (currentCandidate === candidateParts.length) {
+                    // No match, since we still have more of the pattern to hit
+                    return undefined;
+                }
+                var candidatePart = candidateParts[currentCandidate];
+                var gotOneMatchThisCandidate = false;
+                // Consider the case of matching SiUI against SimpleUIElement. The candidate parts
+                // will be Simple/UI/Element, and the pattern parts will be Si/U/I.  We'll match 'Si'
+                // against 'Simple' first.  Then we'll match 'U' against 'UI'. However, we want to
+                // still keep matching pattern parts against that candidate part.
+                for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) {
+                    var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan];
+                    if (gotOneMatchThisCandidate) {
+                        // We've already gotten one pattern part match in this candidate.  We will
+                        // only continue trying to consumer pattern parts if the last part and this
+                        // part are both upper case.
+                        if (!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan - 1].start)) ||
+                            !isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan].start))) {
+                            break;
+                        }
+                    }
+                    if (!partStartsWith(candidate, candidatePart, chunk.text, ignoreCase, chunkCharacterSpan)) {
+                        break;
+                    }
+                    gotOneMatchThisCandidate = true;
+                    firstMatch = firstMatch === undefined ? currentCandidate : firstMatch;
+                    // If we were contiguous, then keep that value.  If we weren't, then keep that
+                    // value.  If we don't know, then set the value to 'true' as an initial match is
+                    // obviously contiguous.
+                    contiguous = contiguous === undefined ? true : contiguous;
+                    candidatePart = ts.createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length);
+                }
+                // Check if we matched anything at all.  If we didn't, then we need to unset the
+                // contiguous bit if we currently had it set.
+                // If we haven't set the bit yet, then that means we haven't matched anything so
+                // far, and we don't want to change that.
+                if (!gotOneMatchThisCandidate && contiguous !== undefined) {
+                    contiguous = false;
+                }
+                // Move onto the next candidate.
+                currentCandidate++;
+            }
+        }
+    }
+    ts.createPatternMatcher = createPatternMatcher;
+    function createSegment(text) {
+        return {
+            totalTextChunk: createTextChunk(text),
+            subWordTextChunks: breakPatternIntoTextChunks(text)
+        };
+    }
+    // A segment is considered invalid if we couldn't find any words in it.
+    function segmentIsInvalid(segment) {
+        return segment.subWordTextChunks.length === 0;
+    }
+    function isUpperCaseLetter(ch) {
+        // Fast check for the ascii range.
+        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
+            return true;
+        }
+        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 5 /* Latest */)) {
+            return false;
+        }
+        // TODO: find a way to determine this for any unicode characters in a
+        // non-allocating manner.
+        var str = String.fromCharCode(ch);
+        return str === str.toUpperCase();
+    }
+    function isLowerCaseLetter(ch) {
+        // Fast check for the ascii range.
+        if (ch >= 97 /* a */ && ch <= 122 /* z */) {
+            return true;
+        }
+        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 5 /* Latest */)) {
+            return false;
+        }
+        // TODO: find a way to determine this for any unicode characters in a
+        // non-allocating manner.
+        var str = String.fromCharCode(ch);
+        return str === str.toLowerCase();
+    }
+    // Assumes 'value' is already lowercase.
+    function indexOfIgnoringCase(string, value) {
+        var n = string.length - value.length;
+        for (var i = 0; i <= n; i++) {
+            if (startsWithIgnoringCase(string, value, i)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    // Assumes 'value' is already lowercase.
+    function startsWithIgnoringCase(string, value, start) {
+        for (var i = 0; i < value.length; i++) {
+            var ch1 = toLowerCase(string.charCodeAt(i + start));
+            var ch2 = value.charCodeAt(i);
+            if (ch1 !== ch2) {
+                return false;
+            }
+        }
+        return true;
+    }
+    function toLowerCase(ch) {
+        // Fast convert for the ascii range.
+        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
+            return 97 /* a */ + (ch - 65 /* A */);
+        }
+        if (ch < 127 /* maxAsciiCharacter */) {
+            return ch;
+        }
+        // TODO: find a way to compute this for any unicode characters in a
+        // non-allocating manner.
+        return String.fromCharCode(ch).toLowerCase().charCodeAt(0);
+    }
+    function isDigit(ch) {
+        // TODO(cyrusn): Find a way to support this for unicode digits.
+        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
+    }
+    function isWordChar(ch) {
+        return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === 95 /* _ */ || ch === 36 /* $ */;
+    }
+    function breakPatternIntoTextChunks(pattern) {
+        var result = [];
+        var wordStart = 0;
+        var wordLength = 0;
+        for (var i = 0; i < pattern.length; i++) {
+            var ch = pattern.charCodeAt(i);
+            if (isWordChar(ch)) {
+                if (wordLength === 0) {
+                    wordStart = i;
+                }
+                wordLength++;
+            }
+            else {
+                if (wordLength > 0) {
+                    result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
+                    wordLength = 0;
+                }
+            }
+        }
+        if (wordLength > 0) {
+            result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
+        }
+        return result;
+    }
+    function createTextChunk(text) {
+        var textLowerCase = text.toLowerCase();
+        return {
+            text: text,
+            textLowerCase: textLowerCase,
+            isLowerCase: text === textLowerCase,
+            characterSpans: breakIntoCharacterSpans(text)
+        };
+    }
+    /* @internal */ function breakIntoCharacterSpans(identifier) {
+        return breakIntoSpans(identifier, /*word:*/ false);
+    }
+    ts.breakIntoCharacterSpans = breakIntoCharacterSpans;
+    /* @internal */ function breakIntoWordSpans(identifier) {
+        return breakIntoSpans(identifier, /*word:*/ true);
+    }
+    ts.breakIntoWordSpans = breakIntoWordSpans;
+    function breakIntoSpans(identifier, word) {
+        var result = [];
+        var wordStart = 0;
+        for (var i = 1; i < identifier.length; i++) {
+            var lastIsDigit = isDigit(identifier.charCodeAt(i - 1));
+            var currentIsDigit = isDigit(identifier.charCodeAt(i));
+            var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i);
+            var hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart);
+            if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
+                charIsPunctuation(identifier.charCodeAt(i)) ||
+                lastIsDigit !== currentIsDigit ||
+                hasTransitionFromLowerToUpper ||
+                hasTransitionFromUpperToLower) {
+                if (!isAllPunctuation(identifier, wordStart, i)) {
+                    result.push(ts.createTextSpan(wordStart, i - wordStart));
+                }
+                wordStart = i;
+            }
+        }
+        if (!isAllPunctuation(identifier, wordStart, identifier.length)) {
+            result.push(ts.createTextSpan(wordStart, identifier.length - wordStart));
+        }
+        return result;
+    }
+    function charIsPunctuation(ch) {
+        switch (ch) {
+            case 33 /* exclamation */:
+            case 34 /* doubleQuote */:
+            case 35 /* hash */:
+            case 37 /* percent */:
+            case 38 /* ampersand */:
+            case 39 /* singleQuote */:
+            case 40 /* openParen */:
+            case 41 /* closeParen */:
+            case 42 /* asterisk */:
+            case 44 /* comma */:
+            case 45 /* minus */:
+            case 46 /* dot */:
+            case 47 /* slash */:
+            case 58 /* colon */:
+            case 59 /* semicolon */:
+            case 63 /* question */:
+            case 64 /* at */:
+            case 91 /* openBracket */:
+            case 92 /* backslash */:
+            case 93 /* closeBracket */:
+            case 95 /* _ */:
+            case 123 /* openBrace */:
+            case 125 /* closeBrace */:
+                return true;
+        }
+        return false;
+    }
+    function isAllPunctuation(identifier, start, end) {
+        for (var i = start; i < end; i++) {
+            var ch = identifier.charCodeAt(i);
+            // We don't consider _ or $ as punctuation as there may be things with that name.
+            if (!charIsPunctuation(ch) || ch === 95 /* _ */ || ch === 36 /* $ */) {
+                return false;
+            }
+        }
+        return true;
+    }
+    function transitionFromUpperToLower(identifier, word, index, wordStart) {
+        if (word) {
+            // Cases this supports:
+            // 1) IDisposable -> I, Disposable
+            // 2) UIElement -> UI, Element
+            // 3) HTMLDocument -> HTML, Document
+            //
+            // etc.
+            if (index !== wordStart &&
+                index + 1 < identifier.length) {
+                var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
+                var nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1));
+                if (currentIsUpper && nextIsLower) {
+                    // We have a transition from an upper to a lower letter here.  But we only
+                    // want to break if all the letters that preceded are uppercase.  i.e. if we
+                    // have "Foo" we don't want to break that into "F, oo".  But if we have
+                    // "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI,
+                    // Foo".  i.e. the last uppercase letter belongs to the lowercase letters
+                    // that follows.  Note: this will make the following not split properly:
+                    // "HELLOthere".  However, these sorts of names do not show up in .Net
+                    // programs.
+                    for (var i = wordStart; i < index; i++) {
+                        if (!isUpperCaseLetter(identifier.charCodeAt(i))) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    function transitionFromLowerToUpper(identifier, word, index) {
+        var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1));
+        var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
+        // See if the casing indicates we're starting a new word. Note: if we're breaking on
+        // words, then just seeing an upper case character isn't enough.  Instead, it has to
+        // be uppercase and the previous character can't be uppercase.
+        //
+        // For example, breaking "AddMetadata" on words would make: Add Metadata
+        //
+        // on characters would be: A dd M etadata
+        //
+        // Break "AM" on words would be: AM
+        //
+        // on characters would be: A M
+        //
+        // We break the search string on characters.  But we break the symbol name on words.
+        var transition = word
+            ? (currentIsUpper && !lastIsUpper)
+            : currentIsUpper;
+        return transition;
+    }
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+    function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
+        if (readImportFiles === void 0) { readImportFiles = true; }
+        if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
+        var referencedFiles = [];
+        var typeReferenceDirectives = [];
+        var importedFiles = [];
+        var ambientExternalModules;
+        var isNoDefaultLib = false;
+        var braceNesting = 0;
+        // assume that text represent an external module if it contains at least one top level import/export
+        // ambient modules that are found inside external modules are interpreted as module augmentations
+        var externalModule = false;
+        function nextToken() {
+            var token = ts.scanner.scan();
+            if (token === 17 /* OpenBraceToken */) {
+                braceNesting++;
+            }
+            else if (token === 18 /* CloseBraceToken */) {
+                braceNesting--;
+            }
+            return token;
+        }
+        function processTripleSlashDirectives() {
+            var commentRanges = ts.getLeadingCommentRanges(sourceText, 0);
+            ts.forEach(commentRanges, function (commentRange) {
+                var comment = sourceText.substring(commentRange.pos, commentRange.end);
+                var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, commentRange);
+                if (referencePathMatchResult) {
+                    isNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
+                    var fileReference = referencePathMatchResult.fileReference;
+                    if (fileReference) {
+                        var collection = referencePathMatchResult.isTypeReferenceDirective
+                            ? typeReferenceDirectives
+                            : referencedFiles;
+                        collection.push(fileReference);
+                    }
+                }
+            });
+        }
+        function getFileReference() {
+            var fileName = ts.scanner.getTokenValue();
+            var pos = ts.scanner.getTokenPos();
+            return { fileName: fileName, pos: pos, end: pos + fileName.length };
+        }
+        function recordAmbientExternalModule() {
+            if (!ambientExternalModules) {
+                ambientExternalModules = [];
+            }
+            ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting });
+        }
+        function recordModuleName() {
+            importedFiles.push(getFileReference());
+            markAsExternalModuleIfTopLevel();
+        }
+        function markAsExternalModuleIfTopLevel() {
+            if (braceNesting === 0) {
+                externalModule = true;
+            }
+        }
+        /**
+         * Returns true if at least one token was consumed from the stream
+         */
+        function tryConsumeDeclare() {
+            var token = ts.scanner.getToken();
+            if (token === 124 /* DeclareKeyword */) {
+                // declare module "mod"
+                token = nextToken();
+                if (token === 128 /* ModuleKeyword */) {
+                    token = nextToken();
+                    if (token === 9 /* StringLiteral */) {
+                        recordAmbientExternalModule();
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        /**
+         * Returns true if at least one token was consumed from the stream
+         */
+        function tryConsumeImport() {
+            var token = ts.scanner.getToken();
+            if (token === 91 /* ImportKeyword */) {
+                token = nextToken();
+                if (token === 19 /* OpenParenToken */) {
+                    token = nextToken();
+                    if (token === 9 /* StringLiteral */) {
+                        // import("mod");
+                        recordModuleName();
+                        return true;
+                    }
+                }
+                else if (token === 9 /* StringLiteral */) {
+                    // import "mod";
+                    recordModuleName();
+                    return true;
+                }
+                else {
+                    if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
+                        token = nextToken();
+                        if (token === 140 /* FromKeyword */) {
+                            token = nextToken();
+                            if (token === 9 /* StringLiteral */) {
+                                // import d from "mod";
+                                recordModuleName();
+                                return true;
+                            }
+                        }
+                        else if (token === 58 /* EqualsToken */) {
+                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
+                                return true;
+                            }
+                        }
+                        else if (token === 26 /* CommaToken */) {
+                            // consume comma and keep going
+                            token = nextToken();
+                        }
+                        else {
+                            // unknown syntax
+                            return true;
+                        }
+                    }
+                    if (token === 17 /* OpenBraceToken */) {
+                        token = nextToken();
+                        // consume "{ a as B, c, d as D}" clauses
+                        // make sure that it stops on EOF
+                        while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
+                            token = nextToken();
+                        }
+                        if (token === 18 /* CloseBraceToken */) {
+                            token = nextToken();
+                            if (token === 140 /* FromKeyword */) {
+                                token = nextToken();
+                                if (token === 9 /* StringLiteral */) {
+                                    // import {a as A} from "mod";
+                                    // import d, {a, b as B} from "mod"
+                                    recordModuleName();
+                                }
+                            }
+                        }
+                    }
+                    else if (token === 39 /* AsteriskToken */) {
+                        token = nextToken();
+                        if (token === 118 /* AsKeyword */) {
+                            token = nextToken();
+                            if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
+                                token = nextToken();
+                                if (token === 140 /* FromKeyword */) {
+                                    token = nextToken();
+                                    if (token === 9 /* StringLiteral */) {
+                                        // import * as NS from "mod"
+                                        // import d, * as NS from "mod"
+                                        recordModuleName();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        function tryConsumeExport() {
+            var token = ts.scanner.getToken();
+            if (token === 84 /* ExportKeyword */) {
+                markAsExternalModuleIfTopLevel();
+                token = nextToken();
+                if (token === 17 /* OpenBraceToken */) {
+                    token = nextToken();
+                    // consume "{ a as B, c, d as D}" clauses
+                    // make sure it stops on EOF
+                    while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
+                        token = nextToken();
+                    }
+                    if (token === 18 /* CloseBraceToken */) {
+                        token = nextToken();
+                        if (token === 140 /* FromKeyword */) {
+                            token = nextToken();
+                            if (token === 9 /* StringLiteral */) {
+                                // export {a as A} from "mod";
+                                // export {a, b as B} from "mod"
+                                recordModuleName();
+                            }
+                        }
+                    }
+                }
+                else if (token === 39 /* AsteriskToken */) {
+                    token = nextToken();
+                    if (token === 140 /* FromKeyword */) {
+                        token = nextToken();
+                        if (token === 9 /* StringLiteral */) {
+                            // export * from "mod"
+                            recordModuleName();
+                        }
+                    }
+                }
+                else if (token === 91 /* ImportKeyword */) {
+                    token = nextToken();
+                    if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
+                        token = nextToken();
+                        if (token === 58 /* EqualsToken */) {
+                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        function tryConsumeRequireCall(skipCurrentToken) {
+            var token = skipCurrentToken ? nextToken() : ts.scanner.getToken();
+            if (token === 132 /* RequireKeyword */) {
+                token = nextToken();
+                if (token === 19 /* OpenParenToken */) {
+                    token = nextToken();
+                    if (token === 9 /* StringLiteral */) {
+                        //  require("mod");
+                        recordModuleName();
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+        function tryConsumeDefine() {
+            var token = ts.scanner.getToken();
+            if (token === 71 /* Identifier */ && ts.scanner.getTokenValue() === "define") {
+                token = nextToken();
+                if (token !== 19 /* OpenParenToken */) {
+                    return true;
+                }
+                token = nextToken();
+                if (token === 9 /* StringLiteral */) {
+                    // looks like define ("modname", ... - skip string literal and comma
+                    token = nextToken();
+                    if (token === 26 /* CommaToken */) {
+                        token = nextToken();
+                    }
+                    else {
+                        // unexpected token
+                        return true;
+                    }
+                }
+                // should be start of dependency list
+                if (token !== 21 /* OpenBracketToken */) {
+                    return true;
+                }
+                // skip open bracket
+                token = nextToken();
+                // scan until ']' or EOF
+                while (token !== 22 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
+                    // record string literals as module names
+                    if (token === 9 /* StringLiteral */) {
+                        recordModuleName();
+                    }
+                    token = nextToken();
+                }
+                return true;
+            }
+            return false;
+        }
+        function processImports() {
+            ts.scanner.setText(sourceText);
+            nextToken();
+            // Look for:
+            //    import "mod";
+            //    import d from "mod"
+            //    import {a as A } from "mod";
+            //    import * as NS  from "mod"
+            //    import d, {a, b as B} from "mod"
+            //    import i = require("mod");
+            //    import("mod");
+            //    export * from "mod"
+            //    export {a as b} from "mod"
+            //    export import i = require("mod")
+            //    (for JavaScript files) require("mod")
+            while (true) {
+                if (ts.scanner.getToken() === 1 /* EndOfFileToken */) {
+                    break;
+                }
+                // check if at least one of alternative have moved scanner forward
+                if (tryConsumeDeclare() ||
+                    tryConsumeImport() ||
+                    tryConsumeExport() ||
+                    (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) {
+                    continue;
+                }
+                else {
+                    nextToken();
+                }
+            }
+            ts.scanner.setText(undefined);
+        }
+        if (readImportFiles) {
+            processImports();
+        }
+        processTripleSlashDirectives();
+        if (externalModule) {
+            // for external modules module all nested ambient modules are augmentations
+            if (ambientExternalModules) {
+                // move all detected ambient modules to imported files since they need to be resolved
+                for (var _i = 0, ambientExternalModules_1 = ambientExternalModules; _i < ambientExternalModules_1.length; _i++) {
+                    var decl = ambientExternalModules_1[_i];
+                    importedFiles.push(decl.ref);
+                }
+            }
+            return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined };
+        }
+        else {
+            // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0
+            var ambientModuleNames = void 0;
+            if (ambientExternalModules) {
+                for (var _a = 0, ambientExternalModules_2 = ambientExternalModules; _a < ambientExternalModules_2.length; _a++) {
+                    var decl = ambientExternalModules_2[_a];
+                    if (decl.depth === 0) {
+                        if (!ambientModuleNames) {
+                            ambientModuleNames = [];
+                        }
+                        ambientModuleNames.push(decl.ref.fileName);
+                    }
+                    else {
+                        importedFiles.push(decl.ref);
+                    }
+                }
+            }
+            return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames };
+        }
+    }
+    ts.preProcessFile = preProcessFile;
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var Rename;
+    (function (Rename) {
+        function getRenameInfo(typeChecker, defaultLibFileName, getCanonicalFileName, sourceFile, position) {
+            var getCanonicalDefaultLibName = ts.memoize(function () { return getCanonicalFileName(ts.normalizePath(defaultLibFileName)); });
+            var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
+            var renameInfo = node && nodeIsEligibleForRename(node)
+                ? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile)
+                : undefined;
+            return renameInfo || getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element);
+            function isDefinedInLibraryFile(declaration) {
+                if (!defaultLibFileName) {
+                    return false;
+                }
+                var sourceFile = declaration.getSourceFile();
+                var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
+                return canonicalName === getCanonicalDefaultLibName();
+            }
+        }
+        Rename.getRenameInfo = getRenameInfo;
+        function getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile) {
+            var symbol = typeChecker.getSymbolAtLocation(node);
+            // Only allow a symbol to be renamed if it actually has at least one declaration.
+            if (symbol) {
+                var declarations = symbol.getDeclarations();
+                if (declarations && declarations.length > 0) {
+                    // Disallow rename for elements that are defined in the standard TypeScript library.
+                    if (ts.some(declarations, isDefinedInLibraryFile)) {
+                        return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
+                    }
+                    // Cannot rename `default` as in `import { default as foo } from "./someModule";
+                    if (node.kind === 71 /* Identifier */ &&
+                        node.originalKeywordKind === 79 /* DefaultKeyword */ &&
+                        symbol.parent.flags & 1536 /* Module */) {
+                        return undefined;
+                    }
+                    var displayName = ts.stripQuotes(ts.getDeclaredName(typeChecker, symbol, node));
+                    var kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
+                    return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, ts.SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined;
+                }
+            }
+            else if (node.kind === 9 /* StringLiteral */) {
+                if (isDefinedInLibraryFile(node)) {
+                    return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
+                }
+                var displayName = ts.stripQuotes(node.text);
+                return getRenameInfoSuccess(displayName, displayName, "var" /* variableElement */, "" /* none */, node, sourceFile);
+            }
+        }
+        function getRenameInfoSuccess(displayName, fullDisplayName, kind, kindModifiers, node, sourceFile) {
+            return {
+                canRename: true,
+                kind: kind,
+                displayName: displayName,
+                localizedErrorMessage: undefined,
+                fullDisplayName: fullDisplayName,
+                kindModifiers: kindModifiers,
+                triggerSpan: createTriggerSpanForNode(node, sourceFile)
+            };
+        }
+        function getRenameInfoError(diagnostic) {
+            return {
+                canRename: false,
+                localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic),
+                displayName: undefined,
+                fullDisplayName: undefined,
+                kind: undefined,
+                kindModifiers: undefined,
+                triggerSpan: undefined
+            };
+        }
+        function createTriggerSpanForNode(node, sourceFile) {
+            var start = node.getStart(sourceFile);
+            var width = node.getWidth(sourceFile);
+            if (node.kind === 9 /* StringLiteral */) {
+                // Exclude the quotes
+                start += 1;
+                width -= 2;
+            }
+            return ts.createTextSpan(start, width);
+        }
+        function nodeIsEligibleForRename(node) {
+            switch (node.kind) {
+                case 71 /* Identifier */:
+                case 9 /* StringLiteral */:
+                case 99 /* ThisKeyword */:
+                    return true;
+                case 8 /* NumericLiteral */:
+                    return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node);
+                default:
+                    return false;
+            }
+        }
+    })(Rename = ts.Rename || (ts.Rename = {}));
+})(ts || (ts = {}));
+///<reference path='services.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var SignatureHelp;
+    (function (SignatureHelp) {
+        var ArgumentListKind;
+        (function (ArgumentListKind) {
+            ArgumentListKind[ArgumentListKind["TypeArguments"] = 0] = "TypeArguments";
+            ArgumentListKind[ArgumentListKind["CallArguments"] = 1] = "CallArguments";
+            ArgumentListKind[ArgumentListKind["TaggedTemplateArguments"] = 2] = "TaggedTemplateArguments";
+            ArgumentListKind[ArgumentListKind["JSXAttributesArguments"] = 3] = "JSXAttributesArguments";
+        })(ArgumentListKind = SignatureHelp.ArgumentListKind || (SignatureHelp.ArgumentListKind = {}));
+        function getSignatureHelpItems(program, sourceFile, position, cancellationToken) {
+            var typeChecker = program.getTypeChecker();
+            // Decide whether to show signature help
+            var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position);
+            if (!startingToken) {
+                // We are at the beginning of the file
+                return undefined;
+            }
+            var argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile);
+            if (!argumentInfo)
+                return undefined;
+            cancellationToken.throwIfCancellationRequested();
+            // Semantic filtering of signature help
+            var call = argumentInfo.invocation;
+            var candidates = [];
+            var resolvedSignature = typeChecker.getResolvedSignature(call, candidates, argumentInfo.argumentCount);
+            cancellationToken.throwIfCancellationRequested();
+            if (!candidates.length) {
+                // We didn't have any sig help items produced by the TS compiler.  If this is a JS
+                // file, then see if we can figure out anything better.
+                if (ts.isSourceFileJavaScript(sourceFile)) {
+                    return createJavaScriptSignatureHelpItems(argumentInfo, program);
+                }
+                return undefined;
+            }
+            return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker);
+        }
+        SignatureHelp.getSignatureHelpItems = getSignatureHelpItems;
+        function createJavaScriptSignatureHelpItems(argumentInfo, program) {
+            if (argumentInfo.invocation.kind !== 181 /* CallExpression */) {
+                return undefined;
+            }
+            // See if we can find some symbol with the call expression name that has call signatures.
+            var callExpression = argumentInfo.invocation;
+            var expression = callExpression.expression;
+            var name = expression.kind === 71 /* Identifier */
+                ? expression
+                : expression.kind === 179 /* PropertyAccessExpression */
+                    ? expression.name
+                    : undefined;
+            if (!name || !name.escapedText) {
+                return undefined;
+            }
+            var typeChecker = program.getTypeChecker();
+            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
+                var sourceFile = _a[_i];
+                var nameToDeclarations = sourceFile.getNamedDeclarations();
+                var declarations = nameToDeclarations.get(name.text);
+                if (declarations) {
+                    for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) {
+                        var declaration = declarations_12[_b];
+                        var symbol = declaration.symbol;
+                        if (symbol) {
+                            var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
+                            if (type) {
+                                var callSignatures = type.getCallSignatures();
+                                if (callSignatures && callSignatures.length) {
+                                    return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        /**
+         * Returns relevant information for the argument list and the current argument if we are
+         * in the argument of an invocation; returns undefined otherwise.
+         */
+        function getImmediatelyContainingArgumentInfo(node, position, sourceFile) {
+            if (ts.isCallOrNewExpression(node.parent)) {
+                var invocation = node.parent;
+                var list = void 0;
+                var argumentIndex = void 0;
+                // There are 3 cases to handle:
+                //   1. The token introduces a list, and should begin a signature help session
+                //   2. The token is either not associated with a list, or ends a list, so the session should end
+                //   3. The token is buried inside a list, and should give signature help
+                //
+                // The following are examples of each:
+                //
+                //    Case 1:
+                //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a signature help session
+                //    Case 2:
+                //          fo#o<T, U>#(a, b)#   -> The token is either not associated with a list, or ends a list, so the session should end
+                //    Case 3:
+                //          foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
+                // Find out if 'node' is an argument, a type argument, or neither
+                if (node.kind === 27 /* LessThanToken */ || node.kind === 19 /* OpenParenToken */) {
+                    // Find the list that starts right *after* the < or ( token.
+                    // If the user has just opened a list, consider this item 0.
+                    list = getChildListThatStartsWithOpenerToken(invocation, node, sourceFile);
+                    ts.Debug.assert(list !== undefined);
+                    argumentIndex = 0;
+                }
+                else {
+                    // findListItemInfo can return undefined if we are not in parent's argument list
+                    // or type argument list. This includes cases where the cursor is:
+                    //   - To the right of the closing parenthesis, non-substitution template, or template tail.
+                    //   - Between the type arguments and the arguments (greater than token)
+                    //   - On the target of the call (parent.func)
+                    //   - On the 'new' keyword in a 'new' expression
+                    list = ts.findContainingList(node);
+                    if (!list)
+                        return undefined;
+                    argumentIndex = getArgumentIndex(list, node);
+                }
+                var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 /* TypeArguments */ : 1 /* CallArguments */;
+                var argumentCount = getArgumentCount(list);
+                if (argumentIndex !== 0) {
+                    ts.Debug.assertLessThan(argumentIndex, argumentCount);
+                }
+                var argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
+                return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
+            }
+            else if (node.kind === 13 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 183 /* TaggedTemplateExpression */) {
+                // Check if we're actually inside the template;
+                // otherwise we'll fall out and return undefined.
+                if (ts.isInsideTemplateLiteral(node, position)) {
+                    return getArgumentListInfoForTemplate(node.parent, /*argumentIndex*/ 0, sourceFile);
+                }
+            }
+            else if (node.kind === 14 /* TemplateHead */ && node.parent.parent.kind === 183 /* TaggedTemplateExpression */) {
+                var templateExpression = node.parent;
+                var tagExpression = templateExpression.parent;
+                ts.Debug.assert(templateExpression.kind === 196 /* TemplateExpression */);
+                var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1;
+                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
+            }
+            else if (node.parent.kind === 205 /* TemplateSpan */ && node.parent.parent.parent.kind === 183 /* TaggedTemplateExpression */) {
+                var templateSpan = node.parent;
+                var templateExpression = templateSpan.parent;
+                var tagExpression = templateExpression.parent;
+                ts.Debug.assert(templateExpression.kind === 196 /* TemplateExpression */);
+                // If we're just after a template tail, don't show signature help.
+                if (node.kind === 16 /* TemplateTail */ && !ts.isInsideTemplateLiteral(node, position)) {
+                    return undefined;
+                }
+                var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
+                var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position);
+                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
+            }
+            else if (node.parent && ts.isJsxOpeningLikeElement(node.parent)) {
+                // Provide a signature help for JSX opening element or JSX self-closing element.
+                // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
+                // i.e
+                //      export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
+                //      <MainButton /*signatureHelp*/
+                var attributeSpanStart = node.parent.attributes.getFullStart();
+                var attributeSpanEnd = ts.skipTrivia(sourceFile.text, node.parent.attributes.getEnd(), /*stopAfterLineBreak*/ false);
+                return {
+                    kind: 3 /* JSXAttributesArguments */,
+                    invocation: node.parent,
+                    argumentsSpan: ts.createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
+                    argumentIndex: 0,
+                    argumentCount: 1
+                };
+            }
+            return undefined;
+        }
+        SignatureHelp.getImmediatelyContainingArgumentInfo = getImmediatelyContainingArgumentInfo;
+        function getArgumentIndex(argumentsList, node) {
+            // The list we got back can include commas.  In the presence of errors it may
+            // also just have nodes without commas.  For example "Foo(a b c)" will have 3
+            // args without commas.   We want to find what index we're at.  So we count
+            // forward until we hit ourselves, only incrementing the index if it isn't a
+            // comma.
+            //
+            // Note: the subtlety around trailing commas (in getArgumentCount) does not apply
+            // here.  That's because we're only walking forward until we hit the node we're
+            // on.  In that case, even if we're after the trailing comma, we'll still see
+            // that trailing comma in the list, and we'll have generated the appropriate
+            // arg index.
+            var argumentIndex = 0;
+            var listChildren = argumentsList.getChildren();
+            for (var _i = 0, listChildren_1 = listChildren; _i < listChildren_1.length; _i++) {
+                var child = listChildren_1[_i];
+                if (child === node) {
+                    break;
+                }
+                if (child.kind !== 26 /* CommaToken */) {
+                    argumentIndex++;
+                }
+            }
+            return argumentIndex;
+        }
+        function getArgumentCount(argumentsList) {
+            // The argument count for a list is normally the number of non-comma children it has.
+            // For example, if you have "Foo(a,b)" then there will be three children of the arg
+            // list 'a' '<comma>' 'b'.  So, in this case the arg count will be 2.  However, there
+            // is a small subtlety.  If you have  "Foo(a,)", then the child list will just have
+            // 'a' '<comma>'.  So, in the case where the last child is a comma, we increase the
+            // arg count by one to compensate.
+            //
+            // Note: this subtlety only applies to the last comma.  If you had "Foo(a,,"  then
+            // we'll have:  'a' '<comma>' '<missing>'
+            // That will give us 2 non-commas.  We then add one for the last comma, giving us an
+            // arg count of 3.
+            var listChildren = argumentsList.getChildren();
+            var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 26 /* CommaToken */; });
+            if (listChildren.length > 0 && ts.lastOrUndefined(listChildren).kind === 26 /* CommaToken */) {
+                argumentCount++;
+            }
+            return argumentCount;
+        }
+        // spanIndex is either the index for a given template span.
+        // This does not give appropriate results for a NoSubstitutionTemplateLiteral
+        function getArgumentIndexForTemplatePiece(spanIndex, node, position) {
+            // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1.
+            // There are three cases we can encounter:
+            //      1. We are precisely in the template literal (argIndex = 0).
+            //      2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1).
+            //      3. We are directly to the right of the template literal, but because we look for the token on the left,
+            //          not enough to put us in the substitution expression; we should consider ourselves part of
+            //          the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1).
+            //
+            // Example: f  `# abcd $#{#  1 + 1#  }# efghi ${ #"#hello"#  }  #  `
+            //              ^       ^ ^       ^   ^          ^ ^      ^     ^
+            // Case:        1       1 3       2   1          3 2      2     1
+            ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
+            if (ts.isTemplateLiteralKind(node.kind)) {
+                if (ts.isInsideTemplateLiteral(node, position)) {
+                    return 0;
+                }
+                return spanIndex + 2;
+            }
+            return spanIndex + 1;
+        }
+        function getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile) {
+            // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
+            var argumentCount = tagExpression.template.kind === 13 /* NoSubstitutionTemplateLiteral */
+                ? 1
+                : tagExpression.template.templateSpans.length + 1;
+            if (argumentIndex !== 0) {
+                ts.Debug.assertLessThan(argumentIndex, argumentCount);
+            }
+            return {
+                kind: 2 /* TaggedTemplateArguments */,
+                invocation: tagExpression,
+                argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
+                argumentIndex: argumentIndex,
+                argumentCount: argumentCount
+            };
+        }
+        function getApplicableSpanForArguments(argumentsList, sourceFile) {
+            // We use full start and skip trivia on the end because we want to include trivia on
+            // both sides. For example,
+            //
+            //    foo(   /*comment */     a, b, c      /*comment*/     )
+            //        |                                               |
+            //
+            // The applicable span is from the first bar to the second bar (inclusive,
+            // but not including parentheses)
+            var applicableSpanStart = argumentsList.getFullStart();
+            var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
+            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
+        }
+        function getApplicableSpanForTaggedTemplate(taggedTemplate, sourceFile) {
+            var template = taggedTemplate.template;
+            var applicableSpanStart = template.getStart();
+            var applicableSpanEnd = template.getEnd();
+            // We need to adjust the end position for the case where the template does not have a tail.
+            // Otherwise, we will not show signature help past the expression.
+            // For example,
+            //
+            //      `  ${ 1 + 1        foo(10)
+            //       |        |
+            //
+            // This is because a Missing node has no width. However, what we actually want is to include trivia
+            // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
+            if (template.kind === 196 /* TemplateExpression */) {
+                var lastSpan = ts.lastOrUndefined(template.templateSpans);
+                if (lastSpan.literal.getFullWidth() === 0) {
+                    applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
+                }
+            }
+            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
+        }
+        function getContainingArgumentInfo(node, position, sourceFile) {
+            for (var n = node; n.kind !== 265 /* SourceFile */; n = n.parent) {
+                if (ts.isFunctionBlock(n)) {
+                    return undefined;
+                }
+                // If the node is not a subspan of its parent, this is a big problem.
+                // There have been crashes that might be caused by this violation.
+                if (n.pos < n.parent.pos || n.end > n.parent.end) {
+                    ts.Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind);
+                }
+                var argumentInfo = getImmediatelyContainingArgumentInfo(n, position, sourceFile);
+                if (argumentInfo) {
+                    return argumentInfo;
+                }
+                // TODO: Handle generic call with incomplete syntax
+            }
+            return undefined;
+        }
+        SignatureHelp.getContainingArgumentInfo = getContainingArgumentInfo;
+        function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
+            var children = parent.getChildren(sourceFile);
+            var indexOfOpenerToken = children.indexOf(openerToken);
+            ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
+            return children[indexOfOpenerToken + 1];
+        }
+        function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) {
+            var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex;
+            var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */;
+            var callTarget = ts.getInvokedExpression(invocation);
+            var callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget);
+            var callTargetDisplayParts = callTargetSymbol && ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
+            var items = ts.map(candidates, function (candidateSignature) {
+                var signatureHelpParameters;
+                var prefixDisplayParts = [];
+                var suffixDisplayParts = [];
+                if (callTargetDisplayParts) {
+                    ts.addRange(prefixDisplayParts, callTargetDisplayParts);
+                }
+                var isVariadic;
+                if (isTypeParameterList) {
+                    isVariadic = false; // type parameter lists are not variadic
+                    prefixDisplayParts.push(ts.punctuationPart(27 /* LessThanToken */));
+                    var typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
+                    signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray;
+                    suffixDisplayParts.push(ts.punctuationPart(29 /* GreaterThanToken */));
+                    var parameterParts = ts.mapToDisplayParts(function (writer) {
+                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation);
+                    });
+                    ts.addRange(suffixDisplayParts, parameterParts);
+                }
+                else {
+                    isVariadic = candidateSignature.hasRestParameter;
+                    var typeParameterParts = ts.mapToDisplayParts(function (writer) {
+                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation);
+                    });
+                    ts.addRange(prefixDisplayParts, typeParameterParts);
+                    prefixDisplayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
+                    signatureHelpParameters = ts.map(candidateSignature.parameters, createSignatureHelpParameterForParameter);
+                    suffixDisplayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
+                }
+                var returnTypeParts = ts.mapToDisplayParts(function (writer) {
+                    return typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation);
+                });
+                ts.addRange(suffixDisplayParts, returnTypeParts);
+                return {
+                    isVariadic: isVariadic,
+                    prefixDisplayParts: prefixDisplayParts,
+                    suffixDisplayParts: suffixDisplayParts,
+                    separatorDisplayParts: [ts.punctuationPart(26 /* CommaToken */), ts.spacePart()],
+                    parameters: signatureHelpParameters,
+                    documentation: candidateSignature.getDocumentationComment(),
+                    tags: candidateSignature.getJsDocTags()
+                };
+            });
+            if (argumentIndex !== 0) {
+                ts.Debug.assertLessThan(argumentIndex, argumentCount);
+            }
+            var selectedItemIndex = candidates.indexOf(resolvedSignature);
+            ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
+            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount };
+            function createSignatureHelpParameterForParameter(parameter) {
+                var displayParts = ts.mapToDisplayParts(function (writer) {
+                    return typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation);
+                });
+                return {
+                    name: parameter.name,
+                    documentation: parameter.getDocumentationComment(),
+                    displayParts: displayParts,
+                    isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration)
+                };
+            }
+            function createSignatureHelpParameterForTypeParameter(typeParameter) {
+                var displayParts = ts.mapToDisplayParts(function (writer) {
+                    return typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation);
+                });
+                return {
+                    name: typeParameter.symbol.name,
+                    documentation: ts.emptyArray,
+                    displayParts: displayParts,
+                    isOptional: false
+                };
+            }
+        }
+    })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var SymbolDisplay;
+    (function (SymbolDisplay) {
+        // TODO(drosen): use contextual SemanticMeaning.
+        function getSymbolKind(typeChecker, symbol, location) {
+            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
+            if (flags & 32 /* Class */) {
+                return ts.getDeclarationOfKind(symbol, 199 /* ClassExpression */) ?
+                    "local class" /* localClassElement */ : "class" /* classElement */;
+            }
+            if (flags & 384 /* Enum */)
+                return "enum" /* enumElement */;
+            if (flags & 524288 /* TypeAlias */)
+                return "type" /* typeElement */;
+            if (flags & 64 /* Interface */)
+                return "interface" /* interfaceElement */;
+            if (flags & 262144 /* TypeParameter */)
+                return "type parameter" /* typeParameterElement */;
+            var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
+            if (result === "" /* unknown */) {
+                if (flags & 262144 /* TypeParameter */)
+                    return "type parameter" /* typeParameterElement */;
+                if (flags & 8 /* EnumMember */)
+                    return "enum member" /* enumMemberElement */;
+                if (flags & 2097152 /* Alias */)
+                    return "alias" /* alias */;
+                if (flags & 1536 /* Module */)
+                    return "module" /* moduleElement */;
+            }
+            return result;
+        }
+        SymbolDisplay.getSymbolKind = getSymbolKind;
+        function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) {
+            if (typeChecker.isUndefinedSymbol(symbol)) {
+                return "var" /* variableElement */;
+            }
+            if (typeChecker.isArgumentsSymbol(symbol)) {
+                return "local var" /* localVariableElement */;
+            }
+            if (location.kind === 99 /* ThisKeyword */ && ts.isExpression(location)) {
+                return "parameter" /* parameterElement */;
+            }
+            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
+            if (flags & 3 /* Variable */) {
+                if (ts.isFirstDeclarationOfSymbolParameter(symbol)) {
+                    return "parameter" /* parameterElement */;
+                }
+                else if (symbol.valueDeclaration && ts.isConst(symbol.valueDeclaration)) {
+                    return "const" /* constElement */;
+                }
+                else if (ts.forEach(symbol.declarations, ts.isLet)) {
+                    return "let" /* letElement */;
+                }
+                return isLocalVariableOrFunction(symbol) ? "local var" /* localVariableElement */ : "var" /* variableElement */;
+            }
+            if (flags & 16 /* Function */)
+                return isLocalVariableOrFunction(symbol) ? "local function" /* localFunctionElement */ : "function" /* functionElement */;
+            if (flags & 32768 /* GetAccessor */)
+                return "getter" /* memberGetAccessorElement */;
+            if (flags & 65536 /* SetAccessor */)
+                return "setter" /* memberSetAccessorElement */;
+            if (flags & 8192 /* Method */)
+                return "method" /* memberFunctionElement */;
+            if (flags & 16384 /* Constructor */)
+                return "constructor" /* constructorImplementationElement */;
+            if (flags & 4 /* Property */) {
+                if (flags & 33554432 /* Transient */ && symbol.checkFlags & 6 /* Synthetic */) {
+                    // If union property is result of union of non method (property/accessors/variables), it is labeled as property
+                    var unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) {
+                        var rootSymbolFlags = rootSymbol.getFlags();
+                        if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) {
+                            return "property" /* memberVariableElement */;
+                        }
+                        // May be a Function if this was from `typeof N` with `namespace N { function f();. }`.
+                        ts.Debug.assert(!!(rootSymbolFlags & (8192 /* Method */ | 16 /* Function */)));
+                    });
+                    if (!unionPropertyKind) {
+                        // If this was union of all methods,
+                        // make sure it has call signatures before we can label it as method
+                        var typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location);
+                        if (typeOfUnionProperty.getCallSignatures().length) {
+                            return "method" /* memberFunctionElement */;
+                        }
+                        return "property" /* memberVariableElement */;
+                    }
+                    return unionPropertyKind;
+                }
+                if (location.parent && ts.isJsxAttribute(location.parent)) {
+                    return "JSX attribute" /* jsxAttribute */;
+                }
+                return "property" /* memberVariableElement */;
+            }
+            return "" /* unknown */;
+        }
+        function getSymbolModifiers(symbol) {
+            return symbol && symbol.declarations && symbol.declarations.length > 0
+                ? ts.getNodeModifiers(symbol.declarations[0])
+                : "" /* none */;
+        }
+        SymbolDisplay.getSymbolModifiers = getSymbolModifiers;
+        // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
+        function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, enclosingDeclaration, location, semanticMeaning) {
+            if (semanticMeaning === void 0) { semanticMeaning = ts.getMeaningFromLocation(location); }
+            var displayParts = [];
+            var documentation;
+            var tags;
+            var symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
+            var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
+            var hasAddedSymbolInfo;
+            var isThisExpression = location.kind === 99 /* ThisKeyword */ && ts.isExpression(location);
+            var type;
+            // Class at constructor site need to be shown as constructor apart from property,method, vars
+            if (symbolKind !== "" /* unknown */ || symbolFlags & 32 /* Class */ || symbolFlags & 2097152 /* Alias */) {
+                // If it is accessor they are allowed only if location is at name of the accessor
+                if (symbolKind === "getter" /* memberGetAccessorElement */ || symbolKind === "setter" /* memberSetAccessorElement */) {
+                    symbolKind = "property" /* memberVariableElement */;
+                }
+                var signature = void 0;
+                type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol.exportSymbol || symbol, location);
+                if (location.parent && location.parent.kind === 179 /* PropertyAccessExpression */) {
+                    var right = location.parent.name;
+                    // Either the location is on the right of a property access, or on the left and the right is missing
+                    if (right === location || (right && right.getFullWidth() === 0)) {
+                        location = location.parent;
+                    }
+                }
+                // try get the call/construct signature from the type if it matches
+                var callExpressionLike = void 0;
+                if (ts.isCallOrNewExpression(location)) {
+                    callExpressionLike = location;
+                }
+                else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) {
+                    callExpressionLike = location.parent;
+                }
+                else if (location.parent && ts.isJsxOpeningLikeElement(location.parent) && ts.isFunctionLike(symbol.valueDeclaration)) {
+                    callExpressionLike = location.parent;
+                }
+                if (callExpressionLike) {
+                    var candidateSignatures = [];
+                    signature = typeChecker.getResolvedSignature(callExpressionLike, candidateSignatures);
+                    var useConstructSignatures = callExpressionLike.kind === 182 /* NewExpression */ || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === 97 /* SuperKeyword */);
+                    var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
+                    if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) {
+                        // Get the first signature if there is one -- allSignatures may contain
+                        // either the original signature or its target, so check for either
+                        signature = allSignatures.length ? allSignatures[0] : undefined;
+                    }
+                    if (signature) {
+                        if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
+                            // Constructor
+                            symbolKind = "constructor" /* constructorImplementationElement */;
+                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
+                        }
+                        else if (symbolFlags & 2097152 /* Alias */) {
+                            symbolKind = "alias" /* alias */;
+                            pushTypePart(symbolKind);
+                            displayParts.push(ts.spacePart());
+                            if (useConstructSignatures) {
+                                displayParts.push(ts.keywordPart(94 /* NewKeyword */));
+                                displayParts.push(ts.spacePart());
+                            }
+                            addFullSymbolName(symbol);
+                        }
+                        else {
+                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
+                        }
+                        switch (symbolKind) {
+                            case "JSX attribute" /* jsxAttribute */:
+                            case "property" /* memberVariableElement */:
+                            case "var" /* variableElement */:
+                            case "const" /* constElement */:
+                            case "let" /* letElement */:
+                            case "parameter" /* parameterElement */:
+                            case "local var" /* localVariableElement */:
+                                // If it is call or construct signature of lambda's write type name
+                                displayParts.push(ts.punctuationPart(56 /* ColonToken */));
+                                displayParts.push(ts.spacePart());
+                                if (useConstructSignatures) {
+                                    displayParts.push(ts.keywordPart(94 /* NewKeyword */));
+                                    displayParts.push(ts.spacePart());
+                                }
+                                if (!(type.flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */) && type.symbol) {
+                                    ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
+                                }
+                                addSignatureDisplayParts(signature, allSignatures, 16 /* WriteArrowStyleSignature */);
+                                break;
+                            default:
+                                // Just signature
+                                addSignatureDisplayParts(signature, allSignatures);
+                        }
+                        hasAddedSymbolInfo = true;
+                    }
+                }
+                else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration
+                    (location.kind === 123 /* ConstructorKeyword */ && location.parent.kind === 152 /* Constructor */)) {
+                    // get the signature from the declaration and write it
+                    var functionDeclaration_1 = location.parent;
+                    // Use function declaration to write the signatures only if the symbol corresponding to this declaration
+                    var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) {
+                        return declaration === (location.kind === 123 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1);
+                    });
+                    if (locationIsSymbolDeclaration) {
+                        var allSignatures = functionDeclaration_1.kind === 152 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
+                        if (!typeChecker.isImplementationOfOverload(functionDeclaration_1)) {
+                            signature = typeChecker.getSignatureFromDeclaration(functionDeclaration_1);
+                        }
+                        else {
+                            signature = allSignatures[0];
+                        }
+                        if (functionDeclaration_1.kind === 152 /* Constructor */) {
+                            // show (constructor) Type(...) signature
+                            symbolKind = "constructor" /* constructorImplementationElement */;
+                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
+                        }
+                        else {
+                            // (function/method) symbol(..signature)
+                            addPrefixForAnyFunctionOrVar(functionDeclaration_1.kind === 155 /* CallSignature */ &&
+                                !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
+                        }
+                        addSignatureDisplayParts(signature, allSignatures);
+                        hasAddedSymbolInfo = true;
+                    }
+                }
+            }
+            if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo && !isThisExpression) {
+                if (ts.getDeclarationOfKind(symbol, 199 /* ClassExpression */)) {
+                    // Special case for class expressions because we would like to indicate that
+                    // the class name is local to the class body (similar to function expression)
+                    //      (local class) class <className>
+                    pushTypePart("local class" /* localClassElement */);
+                }
+                else {
+                    // Class declaration has name which is not local.
+                    displayParts.push(ts.keywordPart(75 /* ClassKeyword */));
+                }
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+                writeTypeParametersOfSymbol(symbol, sourceFile);
+            }
+            if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
+                addNewLineIfDisplayPartsExist();
+                displayParts.push(ts.keywordPart(109 /* InterfaceKeyword */));
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+                writeTypeParametersOfSymbol(symbol, sourceFile);
+            }
+            if (symbolFlags & 524288 /* TypeAlias */) {
+                addNewLineIfDisplayPartsExist();
+                displayParts.push(ts.keywordPart(138 /* TypeKeyword */));
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+                writeTypeParametersOfSymbol(symbol, sourceFile);
+                displayParts.push(ts.spacePart());
+                displayParts.push(ts.operatorPart(58 /* EqualsToken */));
+                displayParts.push(ts.spacePart());
+                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 1024 /* InTypeAlias */));
+            }
+            if (symbolFlags & 384 /* Enum */) {
+                addNewLineIfDisplayPartsExist();
+                if (ts.forEach(symbol.declarations, ts.isConstEnumDeclaration)) {
+                    displayParts.push(ts.keywordPart(76 /* ConstKeyword */));
+                    displayParts.push(ts.spacePart());
+                }
+                displayParts.push(ts.keywordPart(83 /* EnumKeyword */));
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+            }
+            if (symbolFlags & 1536 /* Module */) {
+                addNewLineIfDisplayPartsExist();
+                var declaration = ts.getDeclarationOfKind(symbol, 233 /* ModuleDeclaration */);
+                var isNamespace = declaration && declaration.name && declaration.name.kind === 71 /* Identifier */;
+                displayParts.push(ts.keywordPart(isNamespace ? 129 /* NamespaceKeyword */ : 128 /* ModuleKeyword */));
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+            }
+            if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
+                addNewLineIfDisplayPartsExist();
+                displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
+                displayParts.push(ts.textPart("type parameter"));
+                displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+                if (symbol.parent) {
+                    // Class/Interface type parameter
+                    addInPrefix();
+                    addFullSymbolName(symbol.parent, enclosingDeclaration);
+                    writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
+                }
+                else {
+                    // Method/function type parameter
+                    var decl = ts.getDeclarationOfKind(symbol, 145 /* TypeParameter */);
+                    ts.Debug.assert(decl !== undefined);
+                    var declaration = decl.parent;
+                    if (declaration) {
+                        if (ts.isFunctionLikeKind(declaration.kind)) {
+                            addInPrefix();
+                            var signature = typeChecker.getSignatureFromDeclaration(declaration);
+                            if (declaration.kind === 156 /* ConstructSignature */) {
+                                displayParts.push(ts.keywordPart(94 /* NewKeyword */));
+                                displayParts.push(ts.spacePart());
+                            }
+                            else if (declaration.kind !== 155 /* CallSignature */ && declaration.name) {
+                                addFullSymbolName(declaration.symbol);
+                            }
+                            ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 64 /* WriteTypeArgumentsOfSignature */));
+                        }
+                        else if (declaration.kind === 231 /* TypeAliasDeclaration */) {
+                            // Type alias type parameter
+                            // For example
+                            //      type list<T> = T[];  // Both T will go through same code path
+                            addInPrefix();
+                            displayParts.push(ts.keywordPart(138 /* TypeKeyword */));
+                            displayParts.push(ts.spacePart());
+                            addFullSymbolName(declaration.symbol);
+                            writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
+                        }
+                    }
+                }
+            }
+            if (symbolFlags & 8 /* EnumMember */) {
+                symbolKind = "enum member" /* enumMemberElement */;
+                addPrefixForAnyFunctionOrVar(symbol, "enum member");
+                var declaration = symbol.declarations[0];
+                if (declaration.kind === 264 /* EnumMember */) {
+                    var constantValue = typeChecker.getConstantValue(declaration);
+                    if (constantValue !== undefined) {
+                        displayParts.push(ts.spacePart());
+                        displayParts.push(ts.operatorPart(58 /* EqualsToken */));
+                        displayParts.push(ts.spacePart());
+                        displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral));
+                    }
+                }
+            }
+            if (symbolFlags & 2097152 /* Alias */) {
+                addNewLineIfDisplayPartsExist();
+                switch (symbol.declarations[0].kind) {
+                    case 236 /* NamespaceExportDeclaration */:
+                        displayParts.push(ts.keywordPart(84 /* ExportKeyword */));
+                        displayParts.push(ts.spacePart());
+                        displayParts.push(ts.keywordPart(129 /* NamespaceKeyword */));
+                        break;
+                    case 243 /* ExportAssignment */:
+                        displayParts.push(ts.keywordPart(84 /* ExportKeyword */));
+                        displayParts.push(ts.spacePart());
+                        displayParts.push(ts.keywordPart(symbol.declarations[0].isExportEquals ? 58 /* EqualsToken */ : 79 /* DefaultKeyword */));
+                        break;
+                    default:
+                        displayParts.push(ts.keywordPart(91 /* ImportKeyword */));
+                }
+                displayParts.push(ts.spacePart());
+                addFullSymbolName(symbol);
+                ts.forEach(symbol.declarations, function (declaration) {
+                    if (declaration.kind === 237 /* ImportEqualsDeclaration */) {
+                        var importEqualsDeclaration = declaration;
+                        if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
+                            displayParts.push(ts.spacePart());
+                            displayParts.push(ts.operatorPart(58 /* EqualsToken */));
+                            displayParts.push(ts.spacePart());
+                            displayParts.push(ts.keywordPart(132 /* RequireKeyword */));
+                            displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
+                            displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral));
+                            displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
+                        }
+                        else {
+                            var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
+                            if (internalAliasSymbol) {
+                                displayParts.push(ts.spacePart());
+                                displayParts.push(ts.operatorPart(58 /* EqualsToken */));
+                                displayParts.push(ts.spacePart());
+                                addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
+                            }
+                        }
+                        return true;
+                    }
+                });
+            }
+            if (!hasAddedSymbolInfo) {
+                if (symbolKind !== "" /* unknown */) {
+                    if (type) {
+                        if (isThisExpression) {
+                            addNewLineIfDisplayPartsExist();
+                            displayParts.push(ts.keywordPart(99 /* ThisKeyword */));
+                        }
+                        else {
+                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
+                        }
+                        // For properties, variables and local vars: show the type
+                        if (symbolKind === "property" /* memberVariableElement */ ||
+                            symbolKind === "JSX attribute" /* jsxAttribute */ ||
+                            symbolFlags & 3 /* Variable */ ||
+                            symbolKind === "local var" /* localVariableElement */ ||
+                            isThisExpression) {
+                            displayParts.push(ts.punctuationPart(56 /* ColonToken */));
+                            displayParts.push(ts.spacePart());
+                            // If the type is type parameter, format it specially
+                            if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) {
+                                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
+                                    typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration);
+                                });
+                                ts.addRange(displayParts, typeParameterParts);
+                            }
+                            else {
+                                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration));
+                            }
+                        }
+                        else if (symbolFlags & 16 /* Function */ ||
+                            symbolFlags & 8192 /* Method */ ||
+                            symbolFlags & 16384 /* Constructor */ ||
+                            symbolFlags & 131072 /* Signature */ ||
+                            symbolFlags & 98304 /* Accessor */ ||
+                            symbolKind === "method" /* memberFunctionElement */) {
+                            var allSignatures = type.getNonNullableType().getCallSignatures();
+                            if (allSignatures.length) {
+                                addSignatureDisplayParts(allSignatures[0], allSignatures);
+                            }
+                        }
+                    }
+                }
+                else {
+                    symbolKind = getSymbolKind(typeChecker, symbol, location);
+                }
+            }
+            if (!documentation) {
+                documentation = symbol.getDocumentationComment();
+                tags = symbol.getJsDocTags();
+                if (documentation.length === 0 && symbolFlags & 4 /* Property */) {
+                    // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
+                    // there documentation comments might be attached to the right hand side symbol of their declarations.
+                    // The pattern of such special property access is that the parent symbol is the symbol of the file.
+                    if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 265 /* SourceFile */; })) {
+                        for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                            var declaration = _a[_i];
+                            if (!declaration.parent || declaration.parent.kind !== 194 /* BinaryExpression */) {
+                                continue;
+                            }
+                            var rhsSymbol = typeChecker.getSymbolAtLocation(declaration.parent.right);
+                            if (!rhsSymbol) {
+                                continue;
+                            }
+                            documentation = rhsSymbol.getDocumentationComment();
+                            tags = rhsSymbol.getJsDocTags();
+                            if (documentation.length > 0) {
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags };
+            function addNewLineIfDisplayPartsExist() {
+                if (displayParts.length) {
+                    displayParts.push(ts.lineBreakPart());
+                }
+            }
+            function addInPrefix() {
+                displayParts.push(ts.spacePart());
+                displayParts.push(ts.keywordPart(92 /* InKeyword */));
+                displayParts.push(ts.spacePart());
+            }
+            function addFullSymbolName(symbol, enclosingDeclaration) {
+                var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */);
+                ts.addRange(displayParts, fullSymbolDisplayParts);
+            }
+            function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
+                addNewLineIfDisplayPartsExist();
+                if (symbolKind) {
+                    pushTypePart(symbolKind);
+                    displayParts.push(ts.spacePart());
+                    addFullSymbolName(symbol);
+                }
+            }
+            function pushTypePart(symbolKind) {
+                switch (symbolKind) {
+                    case "var" /* variableElement */:
+                    case "function" /* functionElement */:
+                    case "let" /* letElement */:
+                    case "const" /* constElement */:
+                    case "constructor" /* constructorImplementationElement */:
+                        displayParts.push(ts.textOrKeywordPart(symbolKind));
+                        return;
+                    default:
+                        displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
+                        displayParts.push(ts.textOrKeywordPart(symbolKind));
+                        displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
+                        return;
+                }
+            }
+            function addSignatureDisplayParts(signature, allSignatures, flags) {
+                ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 64 /* WriteTypeArgumentsOfSignature */));
+                if (allSignatures.length > 1) {
+                    displayParts.push(ts.spacePart());
+                    displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
+                    displayParts.push(ts.operatorPart(37 /* PlusToken */));
+                    displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral));
+                    displayParts.push(ts.spacePart());
+                    displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
+                    displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
+                }
+                documentation = signature.getDocumentationComment();
+                tags = signature.getJsDocTags();
+            }
+            function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
+                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
+                    typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
+                });
+                ts.addRange(displayParts, typeParameterParts);
+            }
+        }
+        SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind;
+        function isLocalVariableOrFunction(symbol) {
+            if (symbol.parent) {
+                return false; // This is exported symbol
+            }
+            return ts.forEach(symbol.declarations, function (declaration) {
+                // Function expressions are local
+                if (declaration.kind === 186 /* FunctionExpression */) {
+                    return true;
+                }
+                if (declaration.kind !== 226 /* VariableDeclaration */ && declaration.kind !== 228 /* FunctionDeclaration */) {
+                    return false;
+                }
+                // If the parent is not sourceFile or module block it is local variable
+                for (var parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) {
+                    // Reached source file or module block
+                    if (parent.kind === 265 /* SourceFile */ || parent.kind === 234 /* ModuleBlock */) {
+                        return false;
+                    }
+                }
+                // parent is in function block
+                return true;
+            });
+        }
+    })(SymbolDisplay = ts.SymbolDisplay || (ts.SymbolDisplay = {}));
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+    /*
+     * This function will compile source text from 'input' argument using specified compiler options.
+     * If not options are provided - it will use a set of default compiler options.
+     * Extra compiler options that will unconditionally be used by this function are:
+     * - isolatedModules = true
+     * - allowNonTsExtensions = true
+     * - noLib = true
+     * - noResolve = true
+     */
+    function transpileModule(input, transpileOptions) {
+        var diagnostics = [];
+        var options = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : ts.getDefaultCompilerOptions();
+        options.isolatedModules = true;
+        // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
+        options.suppressOutputPathCheck = true;
+        // Filename can be non-ts file.
+        options.allowNonTsExtensions = true;
+        // We are not returning a sourceFile for lib file when asked by the program,
+        // so pass --noLib to avoid reporting a file not found error.
+        options.noLib = true;
+        // Clear out other settings that would not be used in transpiling this module
+        options.lib = undefined;
+        options.types = undefined;
+        options.noEmit = undefined;
+        options.noEmitOnError = undefined;
+        options.paths = undefined;
+        options.rootDirs = undefined;
+        options.declaration = undefined;
+        options.declarationDir = undefined;
+        options.out = undefined;
+        options.outFile = undefined;
+        // We are not doing a full typecheck, we are not resolving the whole context,
+        // so pass --noResolve to avoid reporting missing file errors.
+        options.noResolve = true;
+        // if jsx is specified then treat file as .tsx
+        var inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts");
+        var sourceFile = ts.createSourceFile(inputFileName, input, options.target);
+        if (transpileOptions.moduleName) {
+            sourceFile.moduleName = transpileOptions.moduleName;
+        }
+        if (transpileOptions.renamedDependencies) {
+            sourceFile.renamedDependencies = ts.createMapFromTemplate(transpileOptions.renamedDependencies);
+        }
+        var newLine = ts.getNewLineCharacter(options);
+        // Output
+        var outputText;
+        var sourceMapText;
+        // Create a compilerHost object to allow the compiler to read and write files
+        var compilerHost = {
+            getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; },
+            writeFile: function (name, text) {
+                if (ts.fileExtensionIs(name, ".map")) {
+                    ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name);
+                    sourceMapText = text;
+                }
+                else {
+                    ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name);
+                    outputText = text;
+                }
+            },
+            getDefaultLibFileName: function () { return "lib.d.ts"; },
+            useCaseSensitiveFileNames: function () { return false; },
+            getCanonicalFileName: function (fileName) { return fileName; },
+            getCurrentDirectory: function () { return ""; },
+            getNewLine: function () { return newLine; },
+            fileExists: function (fileName) { return fileName === inputFileName; },
+            readFile: function () { return ""; },
+            directoryExists: function () { return true; },
+            getDirectories: function () { return []; }
+        };
+        var program = ts.createProgram([inputFileName], options, compilerHost);
+        if (transpileOptions.reportDiagnostics) {
+            ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
+            ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
+        }
+        // Emit
+        program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers);
+        ts.Debug.assert(outputText !== undefined, "Output generation failed");
+        return { outputText: outputText, diagnostics: diagnostics, sourceMapText: sourceMapText };
+    }
+    ts.transpileModule = transpileModule;
+    /*
+     * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
+     */
+    function transpile(input, compilerOptions, fileName, diagnostics, moduleName) {
+        var output = transpileModule(input, { compilerOptions: compilerOptions, fileName: fileName, reportDiagnostics: !!diagnostics, moduleName: moduleName });
+        // addRange correctly handles cases when wither 'from' or 'to' argument is missing
+        ts.addRange(diagnostics, output.diagnostics);
+        return output.outputText;
+    }
+    ts.transpile = transpile;
+    var commandLineOptionsStringToEnum;
+    /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
+    /*@internal*/
+    function fixupCompilerOptions(options, diagnostics) {
+        // Lazily create this value to fix module loading errors.
+        commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || ts.filter(ts.optionDeclarations, function (o) {
+            return typeof o.type === "object" && !ts.forEachEntry(o.type, function (v) { return typeof v !== "number"; });
+        });
+        options = ts.cloneCompilerOptions(options);
+        var _loop_7 = function (opt) {
+            if (!ts.hasProperty(options, opt.name)) {
+                return "continue";
+            }
+            var value = options[opt.name];
+            // Value should be a key of opt.type
+            if (ts.isString(value)) {
+                // If value is not a string, this will fail
+                options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics);
+            }
+            else {
+                if (!ts.forEachEntry(opt.type, function (v) { return v === value; })) {
+                    // Supplied value isn't a valid enum value.
+                    diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt));
+                }
+            }
+        };
+        for (var _i = 0, commandLineOptionsStringToEnum_1 = commandLineOptionsStringToEnum; _i < commandLineOptionsStringToEnum_1.length; _i++) {
+            var opt = commandLineOptionsStringToEnum_1[_i];
+            _loop_7(opt);
+        }
+        return options;
+    }
+    ts.fixupCompilerOptions = fixupCompilerOptions;
+})(ts || (ts = {}));
+/// <reference path="formatting.ts"/>
+/// <reference path="..\..\compiler\scanner.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var standardScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
+        var jsxScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */);
+        var ScanAction;
+        (function (ScanAction) {
+            ScanAction[ScanAction["Scan"] = 0] = "Scan";
+            ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken";
+            ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken";
+            ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken";
+            ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier";
+            ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText";
+        })(ScanAction || (ScanAction = {}));
+        function getFormattingScanner(text, languageVariant, startPos, endPos, cb) {
+            var scanner = languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner;
+            scanner.setText(text);
+            scanner.setTextPos(startPos);
+            var wasNewLine = true;
+            var leadingTrivia;
+            var trailingTrivia;
+            var savedPos;
+            var lastScanAction;
+            var lastTokenInfo;
+            var res = cb({
+                advance: advance,
+                readTokenInfo: readTokenInfo,
+                isOnToken: isOnToken,
+                getCurrentLeadingTrivia: function () { return leadingTrivia; },
+                lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
+                skipToEndOf: skipToEndOf,
+            });
+            lastTokenInfo = undefined;
+            scanner.setText(undefined);
+            return res;
+            function advance() {
+                lastTokenInfo = undefined;
+                var isStarted = scanner.getStartPos() !== startPos;
+                if (isStarted) {
+                    wasNewLine = trailingTrivia && ts.lastOrUndefined(trailingTrivia).kind === 4 /* NewLineTrivia */;
+                }
+                else {
+                    scanner.scan();
+                }
+                leadingTrivia = undefined;
+                trailingTrivia = undefined;
+                var pos = scanner.getStartPos();
+                // Read leading trivia and token
+                while (pos < endPos) {
+                    var t = scanner.getToken();
+                    if (!ts.isTrivia(t)) {
+                        break;
+                    }
+                    // consume leading trivia
+                    scanner.scan();
+                    var item = {
+                        pos: pos,
+                        end: scanner.getStartPos(),
+                        kind: t
+                    };
+                    pos = scanner.getStartPos();
+                    leadingTrivia = ts.append(leadingTrivia, item);
+                }
+                savedPos = scanner.getStartPos();
+            }
+            function shouldRescanGreaterThanToken(node) {
+                switch (node.kind) {
+                    case 31 /* GreaterThanEqualsToken */:
+                    case 66 /* GreaterThanGreaterThanEqualsToken */:
+                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                    case 46 /* GreaterThanGreaterThanToken */:
+                        return true;
+                }
+                return false;
+            }
+            function shouldRescanJsxIdentifier(node) {
+                if (node.parent) {
+                    switch (node.parent.kind) {
+                        case 253 /* JsxAttribute */:
+                        case 251 /* JsxOpeningElement */:
+                        case 252 /* JsxClosingElement */:
+                        case 250 /* JsxSelfClosingElement */:
+                            // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier.
+                            return ts.isKeyword(node.kind) || node.kind === 71 /* Identifier */;
+                    }
+                }
+                return false;
+            }
+            function shouldRescanJsxText(node) {
+                return node.kind === 10 /* JsxText */;
+            }
+            function shouldRescanSlashToken(container) {
+                return container.kind === 12 /* RegularExpressionLiteral */;
+            }
+            function shouldRescanTemplateToken(container) {
+                return container.kind === 15 /* TemplateMiddle */ ||
+                    container.kind === 16 /* TemplateTail */;
+            }
+            function startsWithSlashToken(t) {
+                return t === 41 /* SlashToken */ || t === 63 /* SlashEqualsToken */;
+            }
+            function readTokenInfo(n) {
+                ts.Debug.assert(isOnToken());
+                // normally scanner returns the smallest available token
+                // check the kind of context node to determine if scanner should have more greedy behavior and consume more text.
+                var expectedScanAction = shouldRescanGreaterThanToken(n)
+                    ? 1 /* RescanGreaterThanToken */
+                    : shouldRescanSlashToken(n)
+                        ? 2 /* RescanSlashToken */
+                        : shouldRescanTemplateToken(n)
+                            ? 3 /* RescanTemplateToken */
+                            : shouldRescanJsxIdentifier(n)
+                                ? 4 /* RescanJsxIdentifier */
+                                : shouldRescanJsxText(n)
+                                    ? 5 /* RescanJsxText */
+                                    : 0 /* Scan */;
+                if (lastTokenInfo && expectedScanAction === lastScanAction) {
+                    // readTokenInfo was called before with the same expected scan action.
+                    // No need to re-scan text, return existing 'lastTokenInfo'
+                    // it is ok to call fixTokenKind here since it does not affect
+                    // what portion of text is consumed. In contrast rescanning can change it,
+                    // i.e. for '>=' when originally scanner eats just one character
+                    // and rescanning forces it to consume more.
+                    return fixTokenKind(lastTokenInfo, n);
+                }
+                if (scanner.getStartPos() !== savedPos) {
+                    ts.Debug.assert(lastTokenInfo !== undefined);
+                    // readTokenInfo was called before but scan action differs - rescan text
+                    scanner.setTextPos(savedPos);
+                    scanner.scan();
+                }
+                var currentToken = getNextToken(n, expectedScanAction);
+                var token = {
+                    pos: scanner.getStartPos(),
+                    end: scanner.getTextPos(),
+                    kind: currentToken
+                };
+                // consume trailing trivia
+                if (trailingTrivia) {
+                    trailingTrivia = undefined;
+                }
+                while (scanner.getStartPos() < endPos) {
+                    currentToken = scanner.scan();
+                    if (!ts.isTrivia(currentToken)) {
+                        break;
+                    }
+                    var trivia = {
+                        pos: scanner.getStartPos(),
+                        end: scanner.getTextPos(),
+                        kind: currentToken
+                    };
+                    if (!trailingTrivia) {
+                        trailingTrivia = [];
+                    }
+                    trailingTrivia.push(trivia);
+                    if (currentToken === 4 /* NewLineTrivia */) {
+                        // move past new line
+                        scanner.scan();
+                        break;
+                    }
+                }
+                lastTokenInfo = { leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, token: token };
+                return fixTokenKind(lastTokenInfo, n);
+            }
+            function getNextToken(n, expectedScanAction) {
+                var token = scanner.getToken();
+                lastScanAction = 0 /* Scan */;
+                switch (expectedScanAction) {
+                    case 1 /* RescanGreaterThanToken */:
+                        if (token === 29 /* GreaterThanToken */) {
+                            lastScanAction = 1 /* RescanGreaterThanToken */;
+                            var newToken = scanner.reScanGreaterToken();
+                            ts.Debug.assert(n.kind === newToken);
+                            return newToken;
+                        }
+                        break;
+                    case 2 /* RescanSlashToken */:
+                        if (startsWithSlashToken(token)) {
+                            lastScanAction = 2 /* RescanSlashToken */;
+                            var newToken = scanner.reScanSlashToken();
+                            ts.Debug.assert(n.kind === newToken);
+                            return newToken;
+                        }
+                        break;
+                    case 3 /* RescanTemplateToken */:
+                        if (token === 18 /* CloseBraceToken */) {
+                            lastScanAction = 3 /* RescanTemplateToken */;
+                            return scanner.reScanTemplateToken();
+                        }
+                        break;
+                    case 4 /* RescanJsxIdentifier */:
+                        lastScanAction = 4 /* RescanJsxIdentifier */;
+                        return scanner.scanJsxIdentifier();
+                    case 5 /* RescanJsxText */:
+                        lastScanAction = 5 /* RescanJsxText */;
+                        return scanner.reScanJsxToken();
+                    case 0 /* Scan */:
+                        break;
+                    default:
+                        ts.Debug.assertNever(expectedScanAction);
+                }
+                return token;
+            }
+            function isOnToken() {
+                var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
+                var startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos();
+                return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current);
+            }
+            // when containing node in the tree is token
+            // but its kind differs from the kind that was returned by the scanner,
+            // then kind needs to be fixed. This might happen in cases
+            // when parser interprets token differently, i.e keyword treated as identifier
+            function fixTokenKind(tokenInfo, container) {
+                if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) {
+                    tokenInfo.token.kind = container.kind;
+                }
+                return tokenInfo;
+            }
+            function skipToEndOf(node) {
+                scanner.setTextPos(node.end);
+                savedPos = scanner.getStartPos();
+                lastScanAction = undefined;
+                lastTokenInfo = undefined;
+                wasNewLine = false;
+                leadingTrivia = undefined;
+                trailingTrivia = undefined;
+            }
+        }
+        formatting.getFormattingScanner = getFormattingScanner;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+/// <reference path="references.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var FormattingContext = /** @class */ (function () {
+            function FormattingContext(sourceFile, formattingRequestKind, options) {
+                this.sourceFile = sourceFile;
+                this.formattingRequestKind = formattingRequestKind;
+                this.options = options;
+            }
+            FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) {
+                ts.Debug.assert(currentRange !== undefined, "currentTokenSpan is null");
+                ts.Debug.assert(currentTokenParent !== undefined, "currentTokenParent is null");
+                ts.Debug.assert(nextRange !== undefined, "nextTokenSpan is null");
+                ts.Debug.assert(nextTokenParent !== undefined, "nextTokenParent is null");
+                ts.Debug.assert(commonParent !== undefined, "commonParent is null");
+                this.currentTokenSpan = currentRange;
+                this.currentTokenParent = currentTokenParent;
+                this.nextTokenSpan = nextRange;
+                this.nextTokenParent = nextTokenParent;
+                this.contextNode = commonParent;
+                // drop cached results
+                this.contextNodeAllOnSameLine = undefined;
+                this.nextNodeAllOnSameLine = undefined;
+                this.tokensAreOnSameLine = undefined;
+                this.contextNodeBlockIsOnOneLine = undefined;
+                this.nextNodeBlockIsOnOneLine = undefined;
+            };
+            FormattingContext.prototype.ContextNodeAllOnSameLine = function () {
+                if (this.contextNodeAllOnSameLine === undefined) {
+                    this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode);
+                }
+                return this.contextNodeAllOnSameLine;
+            };
+            FormattingContext.prototype.NextNodeAllOnSameLine = function () {
+                if (this.nextNodeAllOnSameLine === undefined) {
+                    this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
+                }
+                return this.nextNodeAllOnSameLine;
+            };
+            FormattingContext.prototype.TokensAreOnSameLine = function () {
+                if (this.tokensAreOnSameLine === undefined) {
+                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
+                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
+                    this.tokensAreOnSameLine = (startLine === endLine);
+                }
+                return this.tokensAreOnSameLine;
+            };
+            FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () {
+                if (this.contextNodeBlockIsOnOneLine === undefined) {
+                    this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode);
+                }
+                return this.contextNodeBlockIsOnOneLine;
+            };
+            FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () {
+                if (this.nextNodeBlockIsOnOneLine === undefined) {
+                    this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent);
+                }
+                return this.nextNodeBlockIsOnOneLine;
+            };
+            FormattingContext.prototype.NodeIsOnOneLine = function (node) {
+                var startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
+                var endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
+                return startLine === endLine;
+            };
+            FormattingContext.prototype.BlockIsOnOneLine = function (node) {
+                var openBrace = ts.findChildOfKind(node, 17 /* OpenBraceToken */, this.sourceFile);
+                var closeBrace = ts.findChildOfKind(node, 18 /* CloseBraceToken */, this.sourceFile);
+                if (openBrace && closeBrace) {
+                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line;
+                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line;
+                    return startLine === endLine;
+                }
+                return false;
+            };
+            return FormattingContext;
+        }());
+        formatting.FormattingContext = FormattingContext;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+/// <reference path="references.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var FormattingRequestKind;
+        (function (FormattingRequestKind) {
+            FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
+            FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
+            FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
+            FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
+            FormattingRequestKind[FormattingRequestKind["FormatOnOpeningCurlyBrace"] = 4] = "FormatOnOpeningCurlyBrace";
+            FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 5] = "FormatOnClosingCurlyBrace";
+        })(FormattingRequestKind = formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var Rule = /** @class */ (function () {
+            function Rule(Descriptor, Operation, Flag) {
+                if (Flag === void 0) { Flag = 0 /* None */; }
+                this.Descriptor = Descriptor;
+                this.Operation = Operation;
+                this.Flag = Flag;
+            }
+            return Rule;
+        }());
+        formatting.Rule = Rule;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RuleAction;
+        (function (RuleAction) {
+            RuleAction[RuleAction["Ignore"] = 1] = "Ignore";
+            RuleAction[RuleAction["Space"] = 2] = "Space";
+            RuleAction[RuleAction["NewLine"] = 4] = "NewLine";
+            RuleAction[RuleAction["Delete"] = 8] = "Delete";
+        })(RuleAction = formatting.RuleAction || (formatting.RuleAction = {}));
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RuleDescriptor = /** @class */ (function () {
+            function RuleDescriptor(LeftTokenRange, RightTokenRange) {
+                this.LeftTokenRange = LeftTokenRange;
+                this.RightTokenRange = RightTokenRange;
+            }
+            RuleDescriptor.prototype.toString = function () {
+                return "[leftRange=" + this.LeftTokenRange + "," +
+                    "rightRange=" + this.RightTokenRange + "]";
+            };
+            RuleDescriptor.create1 = function (left, right) {
+                return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), formatting.Shared.TokenRange.FromToken(right));
+            };
+            RuleDescriptor.create2 = function (left, right) {
+                return RuleDescriptor.create4(left, formatting.Shared.TokenRange.FromToken(right));
+            };
+            RuleDescriptor.create3 = function (left, right) {
+                return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), right);
+            };
+            RuleDescriptor.create4 = function (left, right) {
+                return new RuleDescriptor(left, right);
+            };
+            return RuleDescriptor;
+        }());
+        formatting.RuleDescriptor = RuleDescriptor;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RuleFlags;
+        (function (RuleFlags) {
+            RuleFlags[RuleFlags["None"] = 0] = "None";
+            RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
+        })(RuleFlags = formatting.RuleFlags || (formatting.RuleFlags = {}));
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RuleOperation = /** @class */ (function () {
+            function RuleOperation(Context, Action) {
+                this.Context = Context;
+                this.Action = Action;
+            }
+            RuleOperation.prototype.toString = function () {
+                return "[context=" + this.Context + "," +
+                    "action=" + this.Action + "]";
+            };
+            RuleOperation.create1 = function (action) {
+                return RuleOperation.create2(formatting.RuleOperationContext.Any, action);
+            };
+            RuleOperation.create2 = function (context, action) {
+                return new RuleOperation(context, action);
+            };
+            return RuleOperation;
+        }());
+        formatting.RuleOperation = RuleOperation;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RuleOperationContext = /** @class */ (function () {
+            function RuleOperationContext() {
+                var funcs = [];
+                for (var _i = 0; _i < arguments.length; _i++) {
+                    funcs[_i] = arguments[_i];
+                }
+                this.customContextChecks = funcs;
+            }
+            RuleOperationContext.prototype.IsAny = function () {
+                return this === RuleOperationContext.Any;
+            };
+            RuleOperationContext.prototype.InContext = function (context) {
+                if (this.IsAny()) {
+                    return true;
+                }
+                for (var _i = 0, _a = this.customContextChecks; _i < _a.length; _i++) {
+                    var check = _a[_i];
+                    if (!check(context)) {
+                        return false;
+                    }
+                }
+                return true;
+            };
+            RuleOperationContext.Any = new RuleOperationContext();
+            return RuleOperationContext;
+        }());
+        formatting.RuleOperationContext = RuleOperationContext;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var Rules = /** @class */ (function () {
+            function Rules() {
+                ///
+                /// Common Rules
+                ///
+                // Leave comments alone
+                this.IgnoreBeforeComment = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.Comments), formatting.RuleOperation.create1(1 /* Ignore */));
+                this.IgnoreAfterLineComment = new formatting.Rule(formatting.RuleDescriptor.create3(2 /* SingleLineCommentTrivia */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create1(1 /* Ignore */));
+                // Space after keyword but not before ; or : or ?
+                this.NoSpaceBeforeSemicolon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 25 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeColon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 56 /* ColonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
+                this.NoSpaceBeforeQuestionMark = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 55 /* QuestionToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
+                this.SpaceAfterColon = new formatting.Rule(formatting.RuleDescriptor.create3(56 /* ColonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterQuestionMarkInConditionalOperator = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConditionalOperatorContext), 2 /* Space */));
+                this.NoSpaceAfterQuestionMark = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.SpaceAfterSemicolon = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                // Space after }.
+                this.SpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* CloseBraceToken */, formatting.Shared.TokenRange.FromRange(0 /* FirstToken */, 142 /* LastToken */, [20 /* CloseParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsAfterCodeBlockContext), 2 /* Space */));
+                // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
+                this.SpaceBetweenCloseBraceAndElse = new formatting.Rule(formatting.RuleDescriptor.create1(18 /* CloseBraceToken */, 82 /* ElseKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBetweenCloseBraceAndWhile = new formatting.Rule(formatting.RuleDescriptor.create1(18 /* CloseBraceToken */, 106 /* WhileKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* CloseBraceToken */, formatting.Shared.TokenRange.FromTokens([22 /* CloseBracketToken */, 26 /* CommaToken */, 25 /* SemicolonToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // No space for dot
+                this.NoSpaceBeforeDot = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 23 /* DotToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterDot = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* DotToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // No space before and after indexer
+                this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.AnyExcept(120 /* AsyncKeyword */), 21 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(22 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), 8 /* Delete */));
+                // Place a space before open brace in a function declaration
+                this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments;
+                this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
+                // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
+                this.TypeScriptOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([71 /* Identifier */, 3 /* MultiLineCommentTrivia */, 75 /* ClassKeyword */, 84 /* ExportKeyword */, 91 /* ImportKeyword */]);
+                this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
+                // Place a space before open brace in a control flow construct
+                this.ControlOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 81 /* DoKeyword */, 102 /* TryKeyword */, 87 /* FinallyKeyword */, 82 /* ElseKeyword */]);
+                this.SpaceBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
+                // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
+                this.SpaceAfterOpenBrace = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), 2 /* Space */));
+                this.SpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), 2 /* Space */));
+                this.NoSpaceAfterOpenBrace = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBetweenEmptyBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(17 /* OpenBraceToken */, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), 8 /* Delete */));
+                // Insert new line after { and before } in multi-line contexts.
+                this.NewLineAfterOpenBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
+                // For functions and control block place } on a new line    [multi-line rule]
+                this.NewLineBeforeCloseBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.AnyIncludingMultilineComments, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
+                // Special handling of unary operators.
+                // Prefix operators generally shouldn't have a space between
+                // them and their target unary expression.
+                this.NoSpaceAfterUnaryPrefixOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.UnaryPrefixOperators, formatting.Shared.TokenRange.UnaryPrefixExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
+                this.NoSpaceAfterUnaryPreincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(43 /* PlusPlusToken */, formatting.Shared.TokenRange.UnaryPreincrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterUnaryPredecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(44 /* MinusMinusToken */, formatting.Shared.TokenRange.UnaryPredecrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeUnaryPostincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostincrementExpressions, 43 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeUnaryPostdecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostdecrementExpressions, 44 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // More unary operator special-casing.
+                // DevDiv 181814:  Be careful when removing leading whitespace
+                // around unary operators.  Examples:
+                //      1 - -2  --X-->  1--2
+                //      a + ++b --X-->  a+++b
+                this.SpaceAfterPostincrementWhenFollowedByAdd = new formatting.Rule(formatting.RuleDescriptor.create1(43 /* PlusPlusToken */, 37 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterAddWhenFollowedByUnaryPlus = new formatting.Rule(formatting.RuleDescriptor.create1(37 /* PlusToken */, 37 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterAddWhenFollowedByPreincrement = new formatting.Rule(formatting.RuleDescriptor.create1(37 /* PlusToken */, 43 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterPostdecrementWhenFollowedBySubtract = new formatting.Rule(formatting.RuleDescriptor.create1(44 /* MinusMinusToken */, 38 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new formatting.Rule(formatting.RuleDescriptor.create1(38 /* MinusToken */, 38 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterSubtractWhenFollowedByPredecrement = new formatting.Rule(formatting.RuleDescriptor.create1(38 /* MinusToken */, 44 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.NoSpaceBeforeComma = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 26 /* CommaToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.SpaceAfterCertainKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([104 /* VarKeyword */, 100 /* ThrowKeyword */, 94 /* NewKeyword */, 80 /* DeleteKeyword */, 96 /* ReturnKeyword */, 103 /* TypeOfKeyword */, 121 /* AwaitKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceAfterNewKeywordOnConstructorSignature = new formatting.Rule(formatting.RuleDescriptor.create1(94 /* NewKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConstructorSignatureContext), 8 /* Delete */));
+                this.SpaceAfterLetConstInVariableDeclaration = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([110 /* LetKeyword */, 76 /* ConstKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), 2 /* Space */));
+                this.NoSpaceBeforeOpenParenInFuncCall = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), 8 /* Delete */));
+                this.SpaceAfterFunctionInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create3(89 /* FunctionKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
+                this.SpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), 2 /* Space */));
+                this.NoSpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), 8 /* Delete */));
+                this.SpaceAfterVoidOperator = new formatting.Rule(formatting.RuleDescriptor.create3(105 /* VoidKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), 2 /* Space */));
+                this.NoSpaceBetweenReturnAndSemicolon = new formatting.Rule(formatting.RuleDescriptor.create1(96 /* ReturnKeyword */, 25 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
+                // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
+                this.SpaceBetweenStatements = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 81 /* DoKeyword */, 82 /* ElseKeyword */, 73 /* CaseKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), 2 /* Space */));
+                // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
+                this.SpaceAfterTryFinally = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([102 /* TryKeyword */, 87 /* FinallyKeyword */]), 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                //      get x() {}
+                //      set x(val) {}
+                this.SpaceAfterGetSetInMember = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([125 /* GetKeyword */, 135 /* SetKeyword */]), 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
+                // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
+                this.SpaceBeforeBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryKeywordOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryKeywordOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                // TypeScript-specific higher priority rules
+                this.SpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(123 /* ConstructorKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(123 /* ConstructorKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // Use of module as a function call. e.g.: import m2 = module("m2");
+                this.NoSpaceAfterModuleImport = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([128 /* ModuleKeyword */, 132 /* RequireKeyword */]), 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // Add a space around certain TypeScript keywords
+                this.SpaceAfterCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([117 /* AbstractKeyword */, 75 /* ClassKeyword */, 124 /* DeclareKeyword */, 79 /* DefaultKeyword */, 83 /* EnumKeyword */, 84 /* ExportKeyword */, 85 /* ExtendsKeyword */, 125 /* GetKeyword */, 108 /* ImplementsKeyword */, 91 /* ImportKeyword */, 109 /* InterfaceKeyword */, 128 /* ModuleKeyword */, 129 /* NamespaceKeyword */, 112 /* PrivateKeyword */, 114 /* PublicKeyword */, 113 /* ProtectedKeyword */, 131 /* ReadonlyKeyword */, 135 /* SetKeyword */, 115 /* StaticKeyword */, 138 /* TypeKeyword */, 140 /* FromKeyword */, 127 /* KeyOfKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBeforeCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([85 /* ExtendsKeyword */, 108 /* ImplementsKeyword */, 140 /* FromKeyword */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
+                this.SpaceAfterModuleName = new formatting.Rule(formatting.RuleDescriptor.create1(9 /* StringLiteral */, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsModuleDeclContext), 2 /* Space */));
+                // Lambda expressions
+                this.SpaceBeforeArrow = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 36 /* EqualsGreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceAfterArrow = new formatting.Rule(formatting.RuleDescriptor.create3(36 /* EqualsGreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                // Optional parameters and let args
+                this.NoSpaceAfterEllipsis = new formatting.Rule(formatting.RuleDescriptor.create1(24 /* DotDotDotToken */, 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterOptionalParameters = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 26 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
+                // generics and type assertions
+                this.NoSpaceBeforeOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.TypeNames, 27 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
+                this.NoSpaceBetweenCloseParenAndAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create1(20 /* CloseParenToken */, 27 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
+                this.NoSpaceAfterOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(27 /* LessThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
+                this.NoSpaceBeforeCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 29 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
+                this.NoSpaceAfterCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.FromTokens([19 /* OpenParenToken */, 21 /* OpenBracketToken */, 29 /* GreaterThanToken */, 26 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
+                // Remove spaces in empty interface literals. e.g.: x: {}
+                this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(17 /* OpenBraceToken */, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectTypeContext), 8 /* Delete */));
+                // decorators
+                this.SpaceBeforeAt = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 57 /* AtToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(57 /* AtToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.SpaceAfterDecorator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([117 /* AbstractKeyword */, 71 /* Identifier */, 84 /* ExportKeyword */, 79 /* DefaultKeyword */, 75 /* ClassKeyword */, 115 /* StaticKeyword */, 114 /* PublicKeyword */, 112 /* PrivateKeyword */, 113 /* ProtectedKeyword */, 125 /* GetKeyword */, 135 /* SetKeyword */, 21 /* OpenBracketToken */, 39 /* AsteriskToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2 /* Space */));
+                this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 39 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8 /* Delete */));
+                this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(39 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([71 /* Identifier */, 19 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */));
+                this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* YieldKeyword */, 39 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */));
+                this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([116 /* YieldKeyword */, 39 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */));
+                // Async-await
+                this.SpaceBetweenAsyncAndOpenParen = new formatting.Rule(formatting.RuleDescriptor.create1(120 /* AsyncKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsArrowFunctionContext, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(120 /* AsyncKeyword */, 89 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                // template string
+                this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(71 /* Identifier */, formatting.Shared.TokenRange.FromTokens([13 /* NoSubstitutionTemplateLiteral */, 14 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // jsx opening element
+                this.SpaceBeforeJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBeforeSlashInJsxOpeningElement = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 41 /* SlashToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new formatting.Rule(formatting.RuleDescriptor.create1(41 /* SlashToken */, 29 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeEqualInJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 58 /* EqualsToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterEqualInJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create3(58 /* EqualsToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // No space before non-null assertion operator
+                this.NoSpaceBeforeNonNullAssertionOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 51 /* ExclamationToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonNullAssertionContext), 8 /* Delete */));
+                ///
+                /// Rules controlled by user options
+                ///
+                // Insert space after comma delimiter
+                this.SpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(26 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), 2 /* Space */));
+                this.NoSpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(26 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), 8 /* Delete */));
+                // Insert space before and after binary operators
+                this.SpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.SpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
+                this.NoSpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
+                this.NoSpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
+                // Insert space after keywords in control flow statements
+                this.SpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), 2 /* Space */));
+                this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), 8 /* Delete */));
+                // Open Brace braces after function
+                // TypeScript: Function can have return types, which can be made of tons of different token kinds
+                this.NewLineBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
+                // Open Brace braces after TypeScript module/class/interface
+                this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
+                // Open Brace braces after control block
+                this.NewLineBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
+                // Insert space after semicolon in for statement
+                this.SpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 2 /* Space */));
+                this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 8 /* Delete */));
+                // Insert space after opening and before closing nonempty parenthesis
+                this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // Insert space after opening and before closing nonempty brackets
+                this.SpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.SpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceBetweenBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(21 /* OpenBracketToken */, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                // Insert space after opening and before closing template string braces
+                this.NoSpaceAfterTemplateHeadAndMiddle = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([14 /* TemplateHead */, 15 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.SpaceAfterTemplateHeadAndMiddle = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([14 /* TemplateHead */, 15 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                this.NoSpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([15 /* TemplateMiddle */, 16 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
+                this.SpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([15 /* TemplateMiddle */, 16 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
+                // No space after { and before } in JSX expression
+                this.NoSpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 8 /* Delete */));
+                this.SpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 2 /* Space */));
+                this.NoSpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 8 /* Delete */));
+                this.SpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 2 /* Space */));
+                // Insert space after function keyword for anonymous functions
+                this.SpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), 2 /* Space */));
+                this.NoSpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), 8 /* Delete */));
+                // No space after type assertion
+                this.NoSpaceAfterTypeAssertion = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), 8 /* Delete */));
+                this.SpaceAfterTypeAssertion = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), 2 /* Space */));
+                // These rules are higher in priority than user-configurable rules.
+                this.HighPriorityCommonRules = [
+                    this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
+                    this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator,
+                    this.NoSpaceAfterQuestionMark,
+                    this.NoSpaceBeforeDot, this.NoSpaceAfterDot,
+                    this.NoSpaceAfterUnaryPrefixOperator,
+                    this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator,
+                    this.NoSpaceBeforeUnaryPostincrementOperator, this.NoSpaceBeforeUnaryPostdecrementOperator,
+                    this.SpaceAfterPostincrementWhenFollowedByAdd,
+                    this.SpaceAfterAddWhenFollowedByUnaryPlus, this.SpaceAfterAddWhenFollowedByPreincrement,
+                    this.SpaceAfterPostdecrementWhenFollowedBySubtract,
+                    this.SpaceAfterSubtractWhenFollowedByUnaryMinus, this.SpaceAfterSubtractWhenFollowedByPredecrement,
+                    this.NoSpaceAfterCloseBrace,
+                    this.NewLineBeforeCloseBraceInBlockContext,
+                    this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets,
+                    this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration,
+                    this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember,
+                    this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand,
+                    this.NoSpaceBetweenReturnAndSemicolon,
+                    this.SpaceAfterCertainKeywords,
+                    this.SpaceAfterLetConstInVariableDeclaration,
+                    this.NoSpaceBeforeOpenParenInFuncCall,
+                    this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
+                    this.SpaceAfterVoidOperator,
+                    this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
+                    this.NoSpaceBetweenTagAndTemplateString,
+                    this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement,
+                    this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
+                    // TypeScript-specific rules
+                    this.NoSpaceAfterModuleImport,
+                    this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords,
+                    this.SpaceAfterModuleName,
+                    this.SpaceBeforeArrow, this.SpaceAfterArrow,
+                    this.NoSpaceAfterEllipsis,
+                    this.NoSpaceAfterOptionalParameters,
+                    this.NoSpaceBetweenEmptyInterfaceBraceBrackets,
+                    this.NoSpaceBeforeOpenAngularBracket,
+                    this.NoSpaceBetweenCloseParenAndAngularBracket,
+                    this.NoSpaceAfterOpenAngularBracket,
+                    this.NoSpaceBeforeCloseAngularBracket,
+                    this.NoSpaceAfterCloseAngularBracket,
+                    this.SpaceBeforeAt,
+                    this.NoSpaceAfterAt,
+                    this.SpaceAfterDecorator,
+                    this.NoSpaceBeforeNonNullAssertionOperator,
+                    this.NoSpaceAfterNewKeywordOnConstructorSignature
+                ];
+                // These rules are applied after high priority rules.
+                this.UserConfigurableRules = [
+                    this.SpaceAfterConstructor, this.NoSpaceAfterConstructor,
+                    this.SpaceAfterComma, this.NoSpaceAfterComma,
+                    this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword,
+                    this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl,
+                    this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen,
+                    this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket,
+                    this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace,
+                    this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
+                    this.SpaceAfterOpenBraceInJsxExpression, this.SpaceBeforeCloseBraceInJsxExpression, this.NoSpaceAfterOpenBraceInJsxExpression, this.NoSpaceBeforeCloseBraceInJsxExpression,
+                    this.SpaceAfterSemicolonInFor, this.NoSpaceAfterSemicolonInFor,
+                    this.SpaceBeforeBinaryOperator, this.SpaceAfterBinaryOperator, this.NoSpaceBeforeBinaryOperator, this.NoSpaceAfterBinaryOperator,
+                    this.SpaceBeforeOpenParenInFuncDecl, this.NoSpaceBeforeOpenParenInFuncDecl,
+                    this.NewLineBeforeOpenBraceInControl,
+                    this.NewLineBeforeOpenBraceInFunction, this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock,
+                    this.SpaceAfterTypeAssertion, this.NoSpaceAfterTypeAssertion
+                ];
+                // These rules are lower in priority than user-configurable rules.
+                this.LowPriorityCommonRules = [
+                    this.NoSpaceBeforeSemicolon,
+                    this.SpaceBeforeOpenBraceInControl, this.SpaceBeforeOpenBraceInFunction, this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock,
+                    this.NoSpaceBeforeComma,
+                    this.NoSpaceBeforeOpenBracket,
+                    this.NoSpaceAfterCloseBracket,
+                    this.SpaceAfterSemicolon,
+                    this.SpaceBetweenStatements, this.SpaceAfterTryFinally
+                ];
+                if (ts.Debug.isDebugging) {
+                    var o = this;
+                    for (var name in o) {
+                        var rule = o[name];
+                        if (rule instanceof formatting.Rule) {
+                            rule.debugName = name;
+                        }
+                    }
+                }
+            }
+            ///
+            /// Contexts
+            ///
+            Rules.IsOptionEnabled = function (optionName) {
+                return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; };
+            };
+            Rules.IsOptionDisabled = function (optionName) {
+                return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; };
+            };
+            Rules.IsOptionDisabledOrUndefined = function (optionName) {
+                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; };
+            };
+            Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine = function (optionName) {
+                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); };
+            };
+            Rules.IsOptionEnabledOrUndefined = function (optionName) {
+                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; };
+            };
+            Rules.IsForContext = function (context) {
+                return context.contextNode.kind === 214 /* ForStatement */;
+            };
+            Rules.IsNotForContext = function (context) {
+                return !Rules.IsForContext(context);
+            };
+            Rules.IsBinaryOpContext = function (context) {
+                switch (context.contextNode.kind) {
+                    case 194 /* BinaryExpression */:
+                    case 195 /* ConditionalExpression */:
+                    case 202 /* AsExpression */:
+                    case 246 /* ExportSpecifier */:
+                    case 242 /* ImportSpecifier */:
+                    case 158 /* TypePredicate */:
+                    case 166 /* UnionType */:
+                    case 167 /* IntersectionType */:
+                        return true;
+                    // equals in binding elements: function foo([[x, y] = [1, 2]])
+                    case 176 /* BindingElement */:
+                    // equals in type X = ...
+                    case 231 /* TypeAliasDeclaration */:
+                    // equal in import a = module('a');
+                    case 237 /* ImportEqualsDeclaration */:
+                    // equal in let a = 0;
+                    case 226 /* VariableDeclaration */:
+                    // equal in p = 0;
+                    case 146 /* Parameter */:
+                    case 264 /* EnumMember */:
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                        return context.currentTokenSpan.kind === 58 /* EqualsToken */ || context.nextTokenSpan.kind === 58 /* EqualsToken */;
+                    // "in" keyword in for (let x in []) { }
+                    case 215 /* ForInStatement */:
+                    // "in" keyword in [P in keyof T]: T[P]
+                    case 145 /* TypeParameter */:
+                        return context.currentTokenSpan.kind === 92 /* InKeyword */ || context.nextTokenSpan.kind === 92 /* InKeyword */;
+                    // Technically, "of" is not a binary operator, but format it the same way as "in"
+                    case 216 /* ForOfStatement */:
+                        return context.currentTokenSpan.kind === 142 /* OfKeyword */ || context.nextTokenSpan.kind === 142 /* OfKeyword */;
+                }
+                return false;
+            };
+            Rules.IsNotBinaryOpContext = function (context) {
+                return !Rules.IsBinaryOpContext(context);
+            };
+            Rules.IsConditionalOperatorContext = function (context) {
+                return context.contextNode.kind === 195 /* ConditionalExpression */;
+            };
+            Rules.IsSameLineTokenOrBeforeBlockContext = function (context) {
+                return context.TokensAreOnSameLine() || Rules.IsBeforeBlockContext(context);
+            };
+            Rules.IsBraceWrappedContext = function (context) {
+                return context.contextNode.kind === 174 /* ObjectBindingPattern */ || Rules.IsSingleLineBlockContext(context);
+            };
+            // This check is done before an open brace in a control construct, a function, or a typescript block declaration
+            Rules.IsBeforeMultilineBlockContext = function (context) {
+                return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
+            };
+            Rules.IsMultilineBlockContext = function (context) {
+                return Rules.IsBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
+            };
+            Rules.IsSingleLineBlockContext = function (context) {
+                return Rules.IsBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
+            };
+            Rules.IsBlockContext = function (context) {
+                return Rules.NodeIsBlockContext(context.contextNode);
+            };
+            Rules.IsBeforeBlockContext = function (context) {
+                return Rules.NodeIsBlockContext(context.nextTokenParent);
+            };
+            // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
+            Rules.NodeIsBlockContext = function (node) {
+                if (Rules.NodeIsTypeScriptDeclWithBlockContext(node)) {
+                    // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
+                    return true;
+                }
+                switch (node.kind) {
+                    case 207 /* Block */:
+                    case 235 /* CaseBlock */:
+                    case 178 /* ObjectLiteralExpression */:
+                    case 234 /* ModuleBlock */:
+                        return true;
+                }
+                return false;
+            };
+            Rules.IsFunctionDeclContext = function (context) {
+                switch (context.contextNode.kind) {
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    // case SyntaxKind.MemberFunctionDeclaration:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    // case SyntaxKind.MethodSignature:
+                    case 155 /* CallSignature */:
+                    case 186 /* FunctionExpression */:
+                    case 152 /* Constructor */:
+                    case 187 /* ArrowFunction */:
+                    // case SyntaxKind.ConstructorDeclaration:
+                    // case SyntaxKind.SimpleArrowFunctionExpression:
+                    // case SyntaxKind.ParenthesizedArrowFunctionExpression:
+                    case 230 /* InterfaceDeclaration */:// This one is not truly a function, but for formatting purposes, it acts just like one
+                        return true;
+                }
+                return false;
+            };
+            Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) {
+                return context.contextNode.kind === 228 /* FunctionDeclaration */ || context.contextNode.kind === 186 /* FunctionExpression */;
+            };
+            Rules.IsTypeScriptDeclWithBlockContext = function (context) {
+                return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode);
+            };
+            Rules.NodeIsTypeScriptDeclWithBlockContext = function (node) {
+                switch (node.kind) {
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 163 /* TypeLiteral */:
+                    case 233 /* ModuleDeclaration */:
+                    case 244 /* ExportDeclaration */:
+                    case 245 /* NamedExports */:
+                    case 238 /* ImportDeclaration */:
+                    case 241 /* NamedImports */:
+                        return true;
+                }
+                return false;
+            };
+            Rules.IsAfterCodeBlockContext = function (context) {
+                switch (context.currentTokenParent.kind) {
+                    case 229 /* ClassDeclaration */:
+                    case 233 /* ModuleDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 260 /* CatchClause */:
+                    case 234 /* ModuleBlock */:
+                    case 221 /* SwitchStatement */:
+                        return true;
+                    case 207 /* Block */: {
+                        var blockParent = context.currentTokenParent.parent;
+                        // In a codefix scenario, we can't rely on parents being set. So just always return true.
+                        if (!blockParent || blockParent.kind !== 187 /* ArrowFunction */ && blockParent.kind !== 186 /* FunctionExpression */) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            };
+            Rules.IsControlDeclContext = function (context) {
+                switch (context.contextNode.kind) {
+                    case 211 /* IfStatement */:
+                    case 221 /* SwitchStatement */:
+                    case 214 /* ForStatement */:
+                    case 215 /* ForInStatement */:
+                    case 216 /* ForOfStatement */:
+                    case 213 /* WhileStatement */:
+                    case 224 /* TryStatement */:
+                    case 212 /* DoStatement */:
+                    case 220 /* WithStatement */:
+                    // TODO
+                    // case SyntaxKind.ElseClause:
+                    case 260 /* CatchClause */:
+                        return true;
+                    default:
+                        return false;
+                }
+            };
+            Rules.IsObjectContext = function (context) {
+                return context.contextNode.kind === 178 /* ObjectLiteralExpression */;
+            };
+            Rules.IsFunctionCallContext = function (context) {
+                return context.contextNode.kind === 181 /* CallExpression */;
+            };
+            Rules.IsNewContext = function (context) {
+                return context.contextNode.kind === 182 /* NewExpression */;
+            };
+            Rules.IsFunctionCallOrNewContext = function (context) {
+                return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context);
+            };
+            Rules.IsPreviousTokenNotComma = function (context) {
+                return context.currentTokenSpan.kind !== 26 /* CommaToken */;
+            };
+            Rules.IsNextTokenNotCloseBracket = function (context) {
+                return context.nextTokenSpan.kind !== 22 /* CloseBracketToken */;
+            };
+            Rules.IsArrowFunctionContext = function (context) {
+                return context.contextNode.kind === 187 /* ArrowFunction */;
+            };
+            Rules.IsNonJsxSameLineTokenContext = function (context) {
+                return context.TokensAreOnSameLine() && context.contextNode.kind !== 10 /* JsxText */;
+            };
+            Rules.IsNonJsxElementContext = function (context) {
+                return context.contextNode.kind !== 249 /* JsxElement */;
+            };
+            Rules.IsJsxExpressionContext = function (context) {
+                return context.contextNode.kind === 256 /* JsxExpression */;
+            };
+            Rules.IsNextTokenParentJsxAttribute = function (context) {
+                return context.nextTokenParent.kind === 253 /* JsxAttribute */;
+            };
+            Rules.IsJsxAttributeContext = function (context) {
+                return context.contextNode.kind === 253 /* JsxAttribute */;
+            };
+            Rules.IsJsxSelfClosingElementContext = function (context) {
+                return context.contextNode.kind === 250 /* JsxSelfClosingElement */;
+            };
+            Rules.IsNotBeforeBlockInFunctionDeclarationContext = function (context) {
+                return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
+            };
+            Rules.IsEndOfDecoratorContextOnSameLine = function (context) {
+                return context.TokensAreOnSameLine() &&
+                    context.contextNode.decorators &&
+                    Rules.NodeIsInDecoratorContext(context.currentTokenParent) &&
+                    !Rules.NodeIsInDecoratorContext(context.nextTokenParent);
+            };
+            Rules.NodeIsInDecoratorContext = function (node) {
+                while (ts.isPartOfExpression(node)) {
+                    node = node.parent;
+                }
+                return node.kind === 147 /* Decorator */;
+            };
+            Rules.IsStartOfVariableDeclarationList = function (context) {
+                return context.currentTokenParent.kind === 227 /* VariableDeclarationList */ &&
+                    context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
+            };
+            Rules.IsNotFormatOnEnter = function (context) {
+                return context.formattingRequestKind !== 2 /* FormatOnEnter */;
+            };
+            Rules.IsModuleDeclContext = function (context) {
+                return context.contextNode.kind === 233 /* ModuleDeclaration */;
+            };
+            Rules.IsObjectTypeContext = function (context) {
+                return context.contextNode.kind === 163 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
+            };
+            Rules.IsConstructorSignatureContext = function (context) {
+                return context.contextNode.kind === 156 /* ConstructSignature */;
+            };
+            Rules.IsTypeArgumentOrParameterOrAssertion = function (token, parent) {
+                if (token.kind !== 27 /* LessThanToken */ && token.kind !== 29 /* GreaterThanToken */) {
+                    return false;
+                }
+                switch (parent.kind) {
+                    case 159 /* TypeReference */:
+                    case 184 /* TypeAssertionExpression */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                    case 187 /* ArrowFunction */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                    case 155 /* CallSignature */:
+                    case 156 /* ConstructSignature */:
+                    case 181 /* CallExpression */:
+                    case 182 /* NewExpression */:
+                    case 201 /* ExpressionWithTypeArguments */:
+                        return true;
+                    default:
+                        return false;
+                }
+            };
+            Rules.IsTypeArgumentOrParameterOrAssertionContext = function (context) {
+                return Rules.IsTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
+                    Rules.IsTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
+            };
+            Rules.IsTypeAssertionContext = function (context) {
+                return context.contextNode.kind === 184 /* TypeAssertionExpression */;
+            };
+            Rules.IsVoidOpContext = function (context) {
+                return context.currentTokenSpan.kind === 105 /* VoidKeyword */ && context.currentTokenParent.kind === 190 /* VoidExpression */;
+            };
+            Rules.IsYieldOrYieldStarWithOperand = function (context) {
+                return context.contextNode.kind === 197 /* YieldExpression */ && context.contextNode.expression !== undefined;
+            };
+            Rules.IsNonNullAssertionContext = function (context) {
+                return context.contextNode.kind === 203 /* NonNullExpression */;
+            };
+            return Rules;
+        }());
+        formatting.Rules = Rules;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RulesMap = /** @class */ (function () {
+            function RulesMap(rules) {
+                this.mapRowLength = 142 /* LastToken */ + 1;
+                this.map = new Array(this.mapRowLength * this.mapRowLength);
+                // This array is used only during construction of the rulesbucket in the map
+                var rulesBucketConstructionStateList = new Array(this.map.length);
+                for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) {
+                    var rule = rules_1[_i];
+                    this.FillRule(rule, rulesBucketConstructionStateList);
+                }
+            }
+            RulesMap.prototype.GetRuleBucketIndex = function (row, column) {
+                ts.Debug.assert(row <= 142 /* LastKeyword */ && column <= 142 /* LastKeyword */, "Must compute formatting context from tokens");
+                return (row * this.mapRowLength) + column;
+            };
+            RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) {
+                var _this = this;
+                var specificRule = rule.Descriptor.LeftTokenRange.isSpecific() && rule.Descriptor.RightTokenRange.isSpecific();
+                rule.Descriptor.LeftTokenRange.GetTokens().forEach(function (left) {
+                    rule.Descriptor.RightTokenRange.GetTokens().forEach(function (right) {
+                        var rulesBucketIndex = _this.GetRuleBucketIndex(left, right);
+                        var rulesBucket = _this.map[rulesBucketIndex];
+                        if (rulesBucket === undefined) {
+                            rulesBucket = _this.map[rulesBucketIndex] = new RulesBucket();
+                        }
+                        rulesBucket.AddRule(rule, specificRule, rulesBucketConstructionStateList, rulesBucketIndex);
+                    });
+                });
+            };
+            RulesMap.prototype.GetRule = function (context) {
+                var bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
+                var bucket = this.map[bucketIndex];
+                if (bucket) {
+                    for (var _i = 0, _a = bucket.Rules(); _i < _a.length; _i++) {
+                        var rule = _a[_i];
+                        if (rule.Operation.Context.InContext(context)) {
+                            return rule;
+                        }
+                    }
+                }
+                return undefined;
+            };
+            return RulesMap;
+        }());
+        formatting.RulesMap = RulesMap;
+        var MaskBitSize = 5;
+        var Mask = 0x1f;
+        var RulesPosition;
+        (function (RulesPosition) {
+            RulesPosition[RulesPosition["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific";
+            RulesPosition[RulesPosition["IgnoreRulesAny"] = MaskBitSize * 1] = "IgnoreRulesAny";
+            RulesPosition[RulesPosition["ContextRulesSpecific"] = MaskBitSize * 2] = "ContextRulesSpecific";
+            RulesPosition[RulesPosition["ContextRulesAny"] = MaskBitSize * 3] = "ContextRulesAny";
+            RulesPosition[RulesPosition["NoContextRulesSpecific"] = MaskBitSize * 4] = "NoContextRulesSpecific";
+            RulesPosition[RulesPosition["NoContextRulesAny"] = MaskBitSize * 5] = "NoContextRulesAny";
+        })(RulesPosition || (RulesPosition = {}));
+        var RulesBucketConstructionState = /** @class */ (function () {
+            function RulesBucketConstructionState() {
+                //// The Rules list contains all the inserted rules into a rulebucket in the following order:
+                ////    1- Ignore rules with specific token combination
+                ////    2- Ignore rules with any token combination
+                ////    3- Context rules with specific token combination
+                ////    4- Context rules with any token combination
+                ////    5- Non-context rules with specific token combination
+                ////    6- Non-context rules with any token combination
+                ////
+                //// The member rulesInsertionIndexBitmap is used to describe the number of rules
+                //// in each sub-bucket (above) hence can be used to know the index of where to insert
+                //// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
+                ////
+                //// Example:
+                //// In order to insert a rule to the end of sub-bucket (3), we get the index by adding
+                //// the values in the bitmap segments 3rd, 2nd, and 1st.
+                this.rulesInsertionIndexBitmap = 0;
+            }
+            RulesBucketConstructionState.prototype.GetInsertionIndex = function (maskPosition) {
+                var index = 0;
+                var pos = 0;
+                var indexBitmap = this.rulesInsertionIndexBitmap;
+                while (pos <= maskPosition) {
+                    index += (indexBitmap & Mask);
+                    indexBitmap >>= MaskBitSize;
+                    pos += MaskBitSize;
+                }
+                return index;
+            };
+            RulesBucketConstructionState.prototype.IncreaseInsertionIndex = function (maskPosition) {
+                var value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask;
+                value++;
+                ts.Debug.assert((value & Mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
+                var temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition);
+                temp |= value << maskPosition;
+                this.rulesInsertionIndexBitmap = temp;
+            };
+            return RulesBucketConstructionState;
+        }());
+        formatting.RulesBucketConstructionState = RulesBucketConstructionState;
+        var RulesBucket = /** @class */ (function () {
+            function RulesBucket() {
+                this.rules = [];
+            }
+            RulesBucket.prototype.Rules = function () {
+                return this.rules;
+            };
+            RulesBucket.prototype.AddRule = function (rule, specificTokens, constructionState, rulesBucketIndex) {
+                var position;
+                if (rule.Operation.Action === 1 /* Ignore */) {
+                    position = specificTokens ?
+                        RulesPosition.IgnoreRulesSpecific :
+                        RulesPosition.IgnoreRulesAny;
+                }
+                else if (!rule.Operation.Context.IsAny()) {
+                    position = specificTokens ?
+                        RulesPosition.ContextRulesSpecific :
+                        RulesPosition.ContextRulesAny;
+                }
+                else {
+                    position = specificTokens ?
+                        RulesPosition.NoContextRulesSpecific :
+                        RulesPosition.NoContextRulesAny;
+                }
+                var state = constructionState[rulesBucketIndex];
+                if (state === undefined) {
+                    state = constructionState[rulesBucketIndex] = new RulesBucketConstructionState();
+                }
+                var index = state.GetInsertionIndex(position);
+                this.rules.splice(index, 0, rule);
+                state.IncreaseInsertionIndex(position);
+            };
+            return RulesBucket;
+        }());
+        formatting.RulesBucket = RulesBucket;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var Shared;
+        (function (Shared) {
+            var allTokens = [];
+            for (var token = 0 /* FirstToken */; token <= 142 /* LastToken */; token++) {
+                allTokens.push(token);
+            }
+            var TokenValuesAccess = /** @class */ (function () {
+                function TokenValuesAccess(tokens) {
+                    if (tokens === void 0) { tokens = []; }
+                    this.tokens = tokens;
+                }
+                TokenValuesAccess.prototype.GetTokens = function () {
+                    return this.tokens;
+                };
+                TokenValuesAccess.prototype.Contains = function (token) {
+                    return this.tokens.indexOf(token) >= 0;
+                };
+                TokenValuesAccess.prototype.isSpecific = function () { return true; };
+                return TokenValuesAccess;
+            }());
+            var TokenSingleValueAccess = /** @class */ (function () {
+                function TokenSingleValueAccess(token) {
+                    this.token = token;
+                }
+                TokenSingleValueAccess.prototype.GetTokens = function () {
+                    return [this.token];
+                };
+                TokenSingleValueAccess.prototype.Contains = function (tokenValue) {
+                    return tokenValue === this.token;
+                };
+                TokenSingleValueAccess.prototype.isSpecific = function () { return true; };
+                return TokenSingleValueAccess;
+            }());
+            var TokenAllAccess = /** @class */ (function () {
+                function TokenAllAccess() {
+                }
+                TokenAllAccess.prototype.GetTokens = function () {
+                    return allTokens;
+                };
+                TokenAllAccess.prototype.Contains = function () {
+                    return true;
+                };
+                TokenAllAccess.prototype.toString = function () {
+                    return "[allTokens]";
+                };
+                TokenAllAccess.prototype.isSpecific = function () { return false; };
+                return TokenAllAccess;
+            }());
+            var TokenAllExceptAccess = /** @class */ (function () {
+                function TokenAllExceptAccess(except) {
+                    this.except = except;
+                }
+                TokenAllExceptAccess.prototype.GetTokens = function () {
+                    var _this = this;
+                    return allTokens.filter(function (t) { return t !== _this.except; });
+                };
+                TokenAllExceptAccess.prototype.Contains = function (token) {
+                    return token !== this.except;
+                };
+                TokenAllExceptAccess.prototype.isSpecific = function () { return false; };
+                return TokenAllExceptAccess;
+            }());
+            var TokenRange;
+            (function (TokenRange) {
+                function FromToken(token) {
+                    return new TokenSingleValueAccess(token);
+                }
+                TokenRange.FromToken = FromToken;
+                function FromTokens(tokens) {
+                    return new TokenValuesAccess(tokens);
+                }
+                TokenRange.FromTokens = FromTokens;
+                function FromRange(from, to, except) {
+                    if (except === void 0) { except = []; }
+                    var tokens = [];
+                    for (var token = from; token <= to; token++) {
+                        if (ts.indexOf(except, token) < 0) {
+                            tokens.push(token);
+                        }
+                    }
+                    return new TokenValuesAccess(tokens);
+                }
+                TokenRange.FromRange = FromRange;
+                function AnyExcept(token) {
+                    return new TokenAllExceptAccess(token);
+                }
+                TokenRange.AnyExcept = AnyExcept;
+                TokenRange.Any = new TokenAllAccess();
+                TokenRange.AnyIncludingMultilineComments = TokenRange.FromTokens(allTokens.concat([3 /* MultiLineCommentTrivia */]));
+                TokenRange.Keywords = TokenRange.FromRange(72 /* FirstKeyword */, 142 /* LastKeyword */);
+                TokenRange.BinaryOperators = TokenRange.FromRange(27 /* FirstBinaryOperator */, 70 /* LastBinaryOperator */);
+                TokenRange.BinaryKeywordOperators = TokenRange.FromTokens([
+                    92 /* InKeyword */, 93 /* InstanceOfKeyword */, 142 /* OfKeyword */, 118 /* AsKeyword */, 126 /* IsKeyword */
+                ]);
+                TokenRange.UnaryPrefixOperators = TokenRange.FromTokens([
+                    43 /* PlusPlusToken */, 44 /* MinusMinusToken */, 52 /* TildeToken */, 51 /* ExclamationToken */
+                ]);
+                TokenRange.UnaryPrefixExpressions = TokenRange.FromTokens([
+                    8 /* NumericLiteral */, 71 /* Identifier */, 19 /* OpenParenToken */, 21 /* OpenBracketToken */,
+                    17 /* OpenBraceToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
+                ]);
+                TokenRange.UnaryPreincrementExpressions = TokenRange.FromTokens([
+                    71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
+                ]);
+                TokenRange.UnaryPostincrementExpressions = TokenRange.FromTokens([
+                    71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */
+                ]);
+                TokenRange.UnaryPredecrementExpressions = TokenRange.FromTokens([
+                    71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
+                ]);
+                TokenRange.UnaryPostdecrementExpressions = TokenRange.FromTokens([
+                    71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */
+                ]);
+                TokenRange.Comments = TokenRange.FromTokens([2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */]);
+                TokenRange.TypeNames = TokenRange.FromTokens([
+                    71 /* Identifier */, 133 /* NumberKeyword */, 136 /* StringKeyword */, 122 /* BooleanKeyword */,
+                    137 /* SymbolKeyword */, 105 /* VoidKeyword */, 119 /* AnyKeyword */
+                ]);
+            })(TokenRange = Shared.TokenRange || (Shared.TokenRange = {}));
+        })(Shared = formatting.Shared || (formatting.Shared = {}));
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='..\services.ts' />
+///<reference path='formattingContext.ts' />
+///<reference path='formattingRequestKind.ts' />
+///<reference path='rule.ts' />
+///<reference path='ruleAction.ts' />
+///<reference path='ruleDescriptor.ts' />
+///<reference path='ruleFlag.ts' />
+///<reference path='ruleOperation.ts' />
+///<reference path='ruleOperationContext.ts' />
+///<reference path='rules.ts' />
+///<reference path='rulesMap.ts' />
+///<reference path='tokenRange.ts' /> 
+/// <reference path="references.ts"/>
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var RulesProvider = /** @class */ (function () {
+            function RulesProvider() {
+                this.globalRules = new formatting.Rules();
+                var activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
+                this.rulesMap = new formatting.RulesMap(activeRules);
+            }
+            RulesProvider.prototype.getRulesMap = function () {
+                return this.rulesMap;
+            };
+            RulesProvider.prototype.getFormatOptions = function () {
+                return this.options;
+            };
+            RulesProvider.prototype.ensureUpToDate = function (options) {
+                if (!this.options || !ts.compareDataObjects(this.options, options)) {
+                    this.options = ts.clone(options);
+                }
+            };
+            return RulesProvider;
+        }());
+        formatting.RulesProvider = RulesProvider;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='..\services.ts' />
+///<reference path='formattingScanner.ts' />
+///<reference path='rulesProvider.ts' />
+///<reference path='references.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var Constants;
+        (function (Constants) {
+            Constants[Constants["Unknown"] = -1] = "Unknown";
+        })(Constants || (Constants = {}));
+        function formatOnEnter(position, sourceFile, rulesProvider, options) {
+            var line = sourceFile.getLineAndCharacterOfPosition(position).line;
+            if (line === 0) {
+                return [];
+            }
+            // After the enter key, the cursor is now at a new line. The new line may or may not contain non-whitespace characters.
+            // If the new line has only whitespaces, we won't want to format this line, because that would remove the indentation as
+            // trailing whitespaces. So the end of the formatting span should be the later one between:
+            //  1. the end of the previous line
+            //  2. the last non-whitespace character in the current line
+            var endOfFormatSpan = ts.getEndLinePosition(line, sourceFile);
+            while (ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) {
+                endOfFormatSpan--;
+            }
+            // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to
+            // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the
+            // previous character before the end of format span is line break character as well.
+            if (ts.isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) {
+                endOfFormatSpan--;
+            }
+            var span = {
+                // get start position for the previous line
+                pos: ts.getStartPositionOfLine(line - 1, sourceFile),
+                // end value is exclusive so add 1 to the result
+                end: endOfFormatSpan + 1
+            };
+            return formatSpan(span, sourceFile, options, rulesProvider, 2 /* FormatOnEnter */);
+        }
+        formatting.formatOnEnter = formatOnEnter;
+        function formatOnSemicolon(position, sourceFile, rulesProvider, options) {
+            var semicolon = findImmediatelyPrecedingTokenOfKind(position, 25 /* SemicolonToken */, sourceFile);
+            return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, options, rulesProvider, 3 /* FormatOnSemicolon */);
+        }
+        formatting.formatOnSemicolon = formatOnSemicolon;
+        function formatOnOpeningCurly(position, sourceFile, rulesProvider, options) {
+            var openingCurly = findImmediatelyPrecedingTokenOfKind(position, 17 /* OpenBraceToken */, sourceFile);
+            if (!openingCurly) {
+                return [];
+            }
+            var curlyBraceRange = openingCurly.parent;
+            var outermostNode = findOutermostNodeWithinListLevel(curlyBraceRange);
+            /**
+             * We limit the span to end at the opening curly to handle the case where
+             * the brace matched to that just typed will be incorrect after further edits.
+             * For example, we could type the opening curly for the following method
+             * body without brace-matching activated:
+             * ```
+             * class C {
+             *     foo()
+             * }
+             * ```
+             * and we wouldn't want to move the closing brace.
+             */
+            var textRange = {
+                pos: ts.getLineStartPositionForPosition(outermostNode.getStart(sourceFile), sourceFile),
+                end: position
+            };
+            return formatSpan(textRange, sourceFile, options, rulesProvider, 4 /* FormatOnOpeningCurlyBrace */);
+        }
+        formatting.formatOnOpeningCurly = formatOnOpeningCurly;
+        function formatOnClosingCurly(position, sourceFile, rulesProvider, options) {
+            var precedingToken = findImmediatelyPrecedingTokenOfKind(position, 18 /* CloseBraceToken */, sourceFile);
+            return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, options, rulesProvider, 5 /* FormatOnClosingCurlyBrace */);
+        }
+        formatting.formatOnClosingCurly = formatOnClosingCurly;
+        function formatDocument(sourceFile, rulesProvider, options) {
+            var span = {
+                pos: 0,
+                end: sourceFile.text.length
+            };
+            return formatSpan(span, sourceFile, options, rulesProvider, 0 /* FormatDocument */);
+        }
+        formatting.formatDocument = formatDocument;
+        function formatSelection(start, end, sourceFile, rulesProvider, options) {
+            // format from the beginning of the line
+            var span = {
+                pos: ts.getLineStartPositionForPosition(start, sourceFile),
+                end: end,
+            };
+            return formatSpan(span, sourceFile, options, rulesProvider, 1 /* FormatSelection */);
+        }
+        formatting.formatSelection = formatSelection;
+        /**
+         * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment).
+         * @param expectedTokenKind The kind of the last token constituting the desired parent node.
+         */
+        function findImmediatelyPrecedingTokenOfKind(end, expectedTokenKind, sourceFile) {
+            var precedingToken = ts.findPrecedingToken(end, sourceFile);
+            return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ?
+                precedingToken :
+                undefined;
+        }
+        /**
+         * Finds the highest node enclosing `node` at the same list level as `node`
+         * and whose end does not exceed `node.end`.
+         *
+         * Consider typing the following
+         * ```
+         * let x = 1;
+         * while (true) {
+         * }
+         * ```
+         * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
+         * variable declaration.
+         */
+        function findOutermostNodeWithinListLevel(node) {
+            var current = node;
+            while (current &&
+                current.parent &&
+                current.parent.end === node.end &&
+                !isListElement(current.parent, current)) {
+                current = current.parent;
+            }
+            return current;
+        }
+        // Returns true if node is a element in some list in parent
+        // i.e. parent is class declaration with the list of members and node is one of members.
+        function isListElement(parent, node) {
+            switch (parent.kind) {
+                case 229 /* ClassDeclaration */:
+                case 230 /* InterfaceDeclaration */:
+                    return ts.rangeContainsRange(parent.members, node);
+                case 233 /* ModuleDeclaration */:
+                    var body = parent.body;
+                    return body && body.kind === 234 /* ModuleBlock */ && ts.rangeContainsRange(body.statements, node);
+                case 265 /* SourceFile */:
+                case 207 /* Block */:
+                case 234 /* ModuleBlock */:
+                    return ts.rangeContainsRange(parent.statements, node);
+                case 260 /* CatchClause */:
+                    return ts.rangeContainsRange(parent.block.statements, node);
+            }
+            return false;
+        }
+        /** find node that fully contains given text range */
+        function findEnclosingNode(range, sourceFile) {
+            return find(sourceFile);
+            function find(n) {
+                var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
+                if (candidate) {
+                    var result = find(candidate);
+                    if (result) {
+                        return result;
+                    }
+                }
+                return n;
+            }
+        }
+        /** formatting is not applied to ranges that contain parse errors.
+         * This function will return a predicate that for a given text range will tell
+         * if there are any parse errors that overlap with the range.
+         */
+        function prepareRangeContainsErrorFunction(errors, originalRange) {
+            if (!errors.length) {
+                return rangeHasNoErrors;
+            }
+            // pick only errors that fall in range
+            var sorted = errors
+                .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); })
+                .sort(function (e1, e2) { return e1.start - e2.start; });
+            if (!sorted.length) {
+                return rangeHasNoErrors;
+            }
+            var index = 0;
+            return function (r) {
+                // in current implementation sequence of arguments [r1, r2...] is monotonically increasing.
+                // 'index' tracks the index of the most recent error that was checked.
+                while (true) {
+                    if (index >= sorted.length) {
+                        // all errors in the range were already checked -> no error in specified range
+                        return false;
+                    }
+                    var error = sorted[index];
+                    if (r.end <= error.start) {
+                        // specified range ends before the error refered by 'index' - no error in range
+                        return false;
+                    }
+                    if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
+                        // specified range overlaps with error range
+                        return true;
+                    }
+                    index++;
+                }
+            };
+            function rangeHasNoErrors() {
+                return false;
+            }
+        }
+        /**
+         * Start of the original range might fall inside the comment - scanner will not yield appropriate results
+         * This function will look for token that is located before the start of target range
+         * and return its end as start position for the scanner.
+         */
+        function getScanStartPosition(enclosingNode, originalRange, sourceFile) {
+            var start = enclosingNode.getStart(sourceFile);
+            if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
+                return start;
+            }
+            var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile);
+            if (!precedingToken) {
+                // no preceding token found - start from the beginning of enclosing node
+                return enclosingNode.pos;
+            }
+            // preceding token ends after the start of original range (i.e when originalRange.pos falls in the middle of literal)
+            // start from the beginning of enclosingNode to handle the entire 'originalRange'
+            if (precedingToken.end >= originalRange.pos) {
+                return enclosingNode.pos;
+            }
+            return precedingToken.end;
+        }
+        /*
+         * For cases like
+         * if (a ||
+         *     b ||$
+         *     c) {...}
+         * If we hit Enter at $ we want line '    b ||' to be indented.
+         * Formatting will be applied to the last two lines.
+         * Node that fully encloses these lines is binary expression 'a ||...'.
+         * Initial indentation for this node will be 0.
+         * Binary expressions don't introduce new indentation scopes, however it is possible
+         * that some parent node on the same line does - like if statement in this case.
+         * Note that we are considering parents only from the same line with initial node -
+         * if parent is on the different line - its delta was already contributed
+         * to the initial indentation.
+         */
+        function getOwnOrInheritedDelta(n, options, sourceFile) {
+            var previousLine = -1 /* Unknown */;
+            var child;
+            while (n) {
+                var line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line;
+                if (previousLine !== -1 /* Unknown */ && line !== previousLine) {
+                    break;
+                }
+                if (formatting.SmartIndenter.shouldIndentChildNode(n, child)) {
+                    return options.indentSize;
+                }
+                previousLine = line;
+                child = n;
+                n = n.parent;
+            }
+            return 0;
+        }
+        /* @internal */
+        function formatNodeGivenIndentation(node, sourceFileLike, languageVariant, initialIndentation, delta, rulesProvider) {
+            var range = { pos: 0, end: sourceFileLike.text.length };
+            return formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, function (scanner) { return formatSpanWorker(range, node, initialIndentation, delta, scanner, rulesProvider.getFormatOptions(), rulesProvider, 1 /* FormatSelection */, function (_) { return false; }, // assume that node does not have any errors
+            sourceFileLike); });
+        }
+        formatting.formatNodeGivenIndentation = formatNodeGivenIndentation;
+        function formatNodeLines(node, sourceFile, options, rulesProvider, requestKind) {
+            if (!node) {
+                return [];
+            }
+            var span = {
+                pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile),
+                end: node.end
+            };
+            return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
+        }
+        function formatSpan(originalRange, sourceFile, options, rulesProvider, requestKind) {
+            // find the smallest node that fully wraps the range and compute the initial indentation for the node
+            var enclosingNode = findEnclosingNode(originalRange, sourceFile);
+            return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options), getOwnOrInheritedDelta(enclosingNode, options, sourceFile), scanner, options, rulesProvider, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); });
+        }
+        function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, options, rulesProvider, requestKind, rangeContainsError, sourceFile) {
+            // formatting context is used by rules provider
+            var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options);
+            var previousRange;
+            var previousParent;
+            var previousRangeStartLine;
+            var lastIndentedLine;
+            var indentationOnLastIndentedLine;
+            var edits = [];
+            formattingScanner.advance();
+            if (formattingScanner.isOnToken()) {
+                var startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line;
+                var undecoratedStartLine = startLine;
+                if (enclosingNode.decorators) {
+                    undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line;
+                }
+                processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
+            }
+            if (!formattingScanner.isOnToken()) {
+                var leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
+                if (leadingTrivia) {
+                    processTrivia(leadingTrivia, enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined);
+                    trimTrailingWhitespacesForRemainingRange();
+                }
+            }
+            return edits;
+            // local functions
+            /** Tries to compute the indentation for a list element.
+             * If list element is not in range then
+             * function will pick its actual indentation
+             * so it can be pushed downstream as inherited indentation.
+             * If list element is in the range - its indentation will be equal
+             * to inherited indentation from its predecessors.
+             */
+            function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) {
+                if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) ||
+                    ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {
+                    if (inheritedIndentation !== -1 /* Unknown */) {
+                        return inheritedIndentation;
+                    }
+                }
+                else {
+                    var startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line;
+                    var startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile);
+                    var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options);
+                    if (startLine !== parentStartLine || startPos === column) {
+                        // Use the base indent size if it is greater than
+                        // the indentation of the inherited predecessor.
+                        var baseIndentSize = formatting.SmartIndenter.getBaseIndentation(options);
+                        return baseIndentSize > column ? baseIndentSize : column;
+                    }
+                }
+                return -1 /* Unknown */;
+            }
+            function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) {
+                var indentation = inheritedIndentation;
+                var delta = formatting.SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
+                if (effectiveParentStartLine === startLine) {
+                    // if node is located on the same line with the parent
+                    // - inherit indentation from the parent
+                    // - push children if either parent of node itself has non-zero delta
+                    indentation = startLine === lastIndentedLine
+                        ? indentationOnLastIndentedLine
+                        : parentDynamicIndentation.getIndentation();
+                    delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta);
+                }
+                else if (indentation === -1 /* Unknown */) {
+                    if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
+                        indentation = parentDynamicIndentation.getIndentation();
+                    }
+                    else {
+                        indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node);
+                    }
+                }
+                return {
+                    indentation: indentation,
+                    delta: delta
+                };
+            }
+            function getFirstNonDecoratorTokenOfNode(node) {
+                if (node.modifiers && node.modifiers.length) {
+                    return node.modifiers[0].kind;
+                }
+                switch (node.kind) {
+                    case 229 /* ClassDeclaration */: return 75 /* ClassKeyword */;
+                    case 230 /* InterfaceDeclaration */: return 109 /* InterfaceKeyword */;
+                    case 228 /* FunctionDeclaration */: return 89 /* FunctionKeyword */;
+                    case 232 /* EnumDeclaration */: return 232 /* EnumDeclaration */;
+                    case 153 /* GetAccessor */: return 125 /* GetKeyword */;
+                    case 154 /* SetAccessor */: return 135 /* SetKeyword */;
+                    case 151 /* MethodDeclaration */:
+                        if (node.asteriskToken) {
+                            return 39 /* AsteriskToken */;
+                        }
+                    // falls through
+                    case 149 /* PropertyDeclaration */:
+                    case 146 /* Parameter */:
+                        return ts.getNameOfDeclaration(node).kind;
+                }
+            }
+            function getDynamicIndentation(node, nodeStartLine, indentation, delta) {
+                return {
+                    getIndentationForComment: function (kind, tokenIndentation, container) {
+                        switch (kind) {
+                            // preceding comment to the token that closes the indentation scope inherits the indentation from the scope
+                            // ..  {
+                            //     // comment
+                            // }
+                            case 18 /* CloseBraceToken */:
+                            case 22 /* CloseBracketToken */:
+                            case 20 /* CloseParenToken */:
+                                return indentation + getEffectiveDelta(delta, container);
+                        }
+                        return tokenIndentation !== -1 /* Unknown */ ? tokenIndentation : indentation;
+                    },
+                    getIndentationForToken: function (line, kind, container) {
+                        if (nodeStartLine !== line && node.decorators) {
+                            if (kind === getFirstNonDecoratorTokenOfNode(node)) {
+                                // if this token is the first token following the list of decorators, we do not need to indent
+                                return indentation;
+                            }
+                        }
+                        switch (kind) {
+                            // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
+                            case 17 /* OpenBraceToken */:
+                            case 18 /* CloseBraceToken */:
+                            case 19 /* OpenParenToken */:
+                            case 20 /* CloseParenToken */:
+                            case 82 /* ElseKeyword */:
+                            case 106 /* WhileKeyword */:
+                            case 57 /* AtToken */:
+                                return indentation;
+                            case 41 /* SlashToken */:
+                            case 29 /* GreaterThanToken */: {
+                                if (container.kind === 251 /* JsxOpeningElement */ ||
+                                    container.kind === 252 /* JsxClosingElement */ ||
+                                    container.kind === 250 /* JsxSelfClosingElement */) {
+                                    return indentation;
+                                }
+                                break;
+                            }
+                            case 21 /* OpenBracketToken */:
+                            case 22 /* CloseBracketToken */: {
+                                if (container.kind !== 172 /* MappedType */) {
+                                    return indentation;
+                                }
+                                break;
+                            }
+                        }
+                        // if token line equals to the line of containing node (this is a first token in the node) - use node indentation
+                        return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation;
+                    },
+                    getIndentation: function () { return indentation; },
+                    getDelta: function (child) { return getEffectiveDelta(delta, child); },
+                    recomputeIndentation: function (lineAdded) {
+                        if (node.parent && formatting.SmartIndenter.shouldIndentChildNode(node.parent, node)) {
+                            if (lineAdded) {
+                                indentation += options.indentSize;
+                            }
+                            else {
+                                indentation -= options.indentSize;
+                            }
+                            if (formatting.SmartIndenter.shouldIndentChildNode(node)) {
+                                delta = options.indentSize;
+                            }
+                            else {
+                                delta = 0;
+                            }
+                        }
+                    }
+                };
+                function getEffectiveDelta(delta, child) {
+                    // Delta value should be zero when the node explicitly prevents indentation of the child node
+                    return formatting.SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0;
+                }
+            }
+            function processNode(node, contextNode, nodeStartLine, undecoratedNodeStartLine, indentation, delta) {
+                if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
+                    return;
+                }
+                var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta);
+                // a useful observations when tracking context node
+                //        /
+                //      [a]
+                //   /   |   \
+                //  [b] [c] [d]
+                // node 'a' is a context node for nodes 'b', 'c', 'd'
+                // except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a'
+                // this rule can be applied recursively to child nodes of 'a'.
+                //
+                // context node is set to parent node value after processing every child node
+                // context node is set to parent of the token after processing every token
+                var childContextNode = contextNode;
+                // if there are any tokens that logically belong to node and interleave child nodes
+                // such tokens will be consumed in processChildNode for for the child that follows them
+                ts.forEachChild(node, function (child) {
+                    processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false);
+                }, function (nodes) {
+                    processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
+                });
+                // proceed any tokens in the node that are located after child nodes
+                while (formattingScanner.isOnToken()) {
+                    var tokenInfo = formattingScanner.readTokenInfo(node);
+                    if (tokenInfo.token.end > node.end) {
+                        break;
+                    }
+                    consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
+                }
+                function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, undecoratedParentStartLine, isListItem, isFirstListItem) {
+                    var childStartPos = child.getStart(sourceFile);
+                    var childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
+                    var undecoratedChildStartLine = childStartLine;
+                    if (child.decorators) {
+                        undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line;
+                    }
+                    // if child is a list item - try to get its indentation, only if parent is within the original range.
+                    var childIndentationAmount = -1 /* Unknown */;
+                    if (isListItem && ts.rangeContainsRange(originalRange, parent)) {
+                        childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation);
+                        if (childIndentationAmount !== -1 /* Unknown */) {
+                            inheritedIndentation = childIndentationAmount;
+                        }
+                    }
+                    // child node is outside the target range - do not dive inside
+                    if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
+                        if (child.end < originalRange.pos) {
+                            formattingScanner.skipToEndOf(child);
+                        }
+                        return inheritedIndentation;
+                    }
+                    if (child.getFullWidth() === 0) {
+                        return inheritedIndentation;
+                    }
+                    while (formattingScanner.isOnToken()) {
+                        // proceed any parent tokens that are located prior to child.getStart()
+                        var tokenInfo = formattingScanner.readTokenInfo(node);
+                        if (tokenInfo.token.end > childStartPos) {
+                            // stop when formatting scanner advances past the beginning of the child
+                            break;
+                        }
+                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node);
+                    }
+                    if (!formattingScanner.isOnToken()) {
+                        return inheritedIndentation;
+                    }
+                    // JSX text shouldn't affect indenting
+                    if (ts.isToken(child) && child.kind !== 10 /* JsxText */) {
+                        // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules
+                        var tokenInfo = formattingScanner.readTokenInfo(child);
+                        ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end");
+                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
+                        return inheritedIndentation;
+                    }
+                    var effectiveParentStartLine = child.kind === 147 /* Decorator */ ? childStartLine : undecoratedParentStartLine;
+                    var childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine);
+                    processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
+                    childContextNode = node;
+                    if (isFirstListItem && parent.kind === 177 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) {
+                        inheritedIndentation = childIndentation.indentation;
+                    }
+                    return inheritedIndentation;
+                }
+                function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
+                    ts.Debug.assert(ts.isNodeArray(nodes));
+                    var listStartToken = getOpenTokenForList(parent, nodes);
+                    var listEndToken = getCloseTokenForOpenToken(listStartToken);
+                    var listDynamicIndentation = parentDynamicIndentation;
+                    var startLine = parentStartLine;
+                    if (listStartToken !== 0 /* Unknown */) {
+                        // introduce a new indentation scope for lists (including list start and end tokens)
+                        while (formattingScanner.isOnToken()) {
+                            var tokenInfo = formattingScanner.readTokenInfo(parent);
+                            if (tokenInfo.token.end > nodes.pos) {
+                                // stop when formatting scanner moves past the beginning of node list
+                                break;
+                            }
+                            else if (tokenInfo.token.kind === listStartToken) {
+                                // consume list start token
+                                startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
+                                var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, parentStartLine);
+                                listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta);
+                                consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
+                            }
+                            else {
+                                // consume any tokens that precede the list as child elements of 'node' using its indentation scope
+                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
+                            }
+                        }
+                    }
+                    var inheritedIndentation = -1 /* Unknown */;
+                    for (var i = 0; i < nodes.length; i++) {
+                        var child = nodes[i];
+                        inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0);
+                    }
+                    if (listEndToken !== 0 /* Unknown */) {
+                        if (formattingScanner.isOnToken()) {
+                            var tokenInfo = formattingScanner.readTokenInfo(parent);
+                            // consume the list end token only if it is still belong to the parent
+                            // there might be the case when current token matches end token but does not considered as one
+                            // function (x: function) <--
+                            // without this check close paren will be interpreted as list end token for function expression which is wrong
+                            if (tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) {
+                                // consume list end token
+                                consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
+                            }
+                        }
+                    }
+                }
+                function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation, container) {
+                    ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token));
+                    var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
+                    var indentToken = false;
+                    if (currentTokenInfo.leadingTrivia) {
+                        processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation);
+                    }
+                    var lineAdded;
+                    var isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token);
+                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(currentTokenInfo.token.pos);
+                    if (isTokenInRange) {
+                        var rangeHasError = rangeContainsError(currentTokenInfo.token);
+                        // save previousRange since processRange will overwrite this value with current one
+                        var savePreviousRange = previousRange;
+                        lineAdded = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
+                        if (rangeHasError) {
+                            // do not indent comments\token if token range overlaps with some error
+                            indentToken = false;
+                        }
+                        else {
+                            if (lineAdded !== undefined) {
+                                indentToken = lineAdded;
+                            }
+                            else {
+                                // indent token only if end line of previous range does not match start line of the token
+                                var prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
+                                indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
+                            }
+                        }
+                    }
+                    if (currentTokenInfo.trailingTrivia) {
+                        processTrivia(currentTokenInfo.trailingTrivia, parent, childContextNode, dynamicIndentation);
+                    }
+                    if (indentToken) {
+                        var tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ?
+                            dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container) :
+                            -1 /* Unknown */;
+                        var indentNextTokenOrTrivia = true;
+                        if (currentTokenInfo.leadingTrivia) {
+                            var commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
+                            for (var _i = 0, _a = currentTokenInfo.leadingTrivia; _i < _a.length; _i++) {
+                                var triviaItem = _a[_i];
+                                var triviaInRange = ts.rangeContainsRange(originalRange, triviaItem);
+                                switch (triviaItem.kind) {
+                                    case 3 /* MultiLineCommentTrivia */:
+                                        if (triviaInRange) {
+                                            indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
+                                        }
+                                        indentNextTokenOrTrivia = false;
+                                        break;
+                                    case 2 /* SingleLineCommentTrivia */:
+                                        if (indentNextTokenOrTrivia && triviaInRange) {
+                                            insertIndentation(triviaItem.pos, commentIndentation, /*lineAdded*/ false);
+                                        }
+                                        indentNextTokenOrTrivia = false;
+                                        break;
+                                    case 4 /* NewLineTrivia */:
+                                        indentNextTokenOrTrivia = true;
+                                        break;
+                                }
+                            }
+                        }
+                        // indent token only if is it is in target range and does not overlap with any error ranges
+                        if (tokenIndentation !== -1 /* Unknown */ && indentNextTokenOrTrivia) {
+                            insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded);
+                            lastIndentedLine = tokenStart.line;
+                            indentationOnLastIndentedLine = tokenIndentation;
+                        }
+                    }
+                    formattingScanner.advance();
+                    childContextNode = parent;
+                }
+            }
+            function processTrivia(trivia, parent, contextNode, dynamicIndentation) {
+                for (var _i = 0, trivia_1 = trivia; _i < trivia_1.length; _i++) {
+                    var triviaItem = trivia_1[_i];
+                    if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) {
+                        var triviaItemStart = sourceFile.getLineAndCharacterOfPosition(triviaItem.pos);
+                        processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation);
+                    }
+                }
+            }
+            function processRange(range, rangeStart, parent, contextNode, dynamicIndentation) {
+                var rangeHasError = rangeContainsError(range);
+                var lineAdded;
+                if (!rangeHasError) {
+                    if (!previousRange) {
+                        // trim whitespaces starting from the beginning of the span up to the current line
+                        var originalStart = sourceFile.getLineAndCharacterOfPosition(originalRange.pos);
+                        trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
+                    }
+                    else {
+                        lineAdded =
+                            processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation);
+                    }
+                }
+                previousRange = range;
+                previousParent = parent;
+                previousRangeStartLine = rangeStart.line;
+                return lineAdded;
+            }
+            function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) {
+                formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
+                var rule = rulesProvider.getRulesMap().GetRule(formattingContext);
+                var trimTrailingWhitespaces;
+                var lineAdded;
+                if (rule) {
+                    applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
+                    if (rule.Operation.Action & (2 /* Space */ | 8 /* Delete */) && currentStartLine !== previousStartLine) {
+                        lineAdded = false;
+                        // Handle the case where the next line is moved to be the end of this line.
+                        // In this case we don't indent the next line in the next pass.
+                        if (currentParent.getStart(sourceFile) === currentItem.pos) {
+                            dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
+                        }
+                    }
+                    else if (rule.Operation.Action & 4 /* NewLine */ && currentStartLine === previousStartLine) {
+                        lineAdded = true;
+                        // Handle the case where token2 is moved to the new line.
+                        // In this case we indent token2 in the next pass but we set
+                        // sameLineIndent flag to notify the indenter that the indentation is within the line.
+                        if (currentParent.getStart(sourceFile) === currentItem.pos) {
+                            dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
+                        }
+                    }
+                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
+                    trimTrailingWhitespaces = !(rule.Operation.Action & 8 /* Delete */) && rule.Flag !== 1 /* CanDeleteNewLines */;
+                }
+                else {
+                    trimTrailingWhitespaces = true;
+                }
+                if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
+                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
+                    trimTrailingWhitespacesForLines(previousStartLine, currentStartLine, previousItem);
+                }
+                return lineAdded;
+            }
+            function insertIndentation(pos, indentation, lineAdded) {
+                var indentationString = getIndentationString(indentation, options);
+                if (lineAdded) {
+                    // new line is added before the token by the formatting rules
+                    // insert indentation string at the very beginning of the token
+                    recordReplace(pos, 0, indentationString);
+                }
+                else {
+                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(pos);
+                    var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile);
+                    if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) {
+                        recordReplace(startLinePosition, tokenStart.character, indentationString);
+                    }
+                }
+            }
+            function characterToColumn(startLinePosition, characterInLine) {
+                var column = 0;
+                for (var i = 0; i < characterInLine; i++) {
+                    if (sourceFile.text.charCodeAt(startLinePosition + i) === 9 /* tab */) {
+                        column += options.tabSize - column % options.tabSize;
+                    }
+                    else {
+                        column++;
+                    }
+                }
+                return column;
+            }
+            function indentationIsDifferent(indentationString, startLinePosition) {
+                return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
+            }
+            function indentMultilineComment(commentRange, indentation, firstLineIsIndented) {
+                // split comment in lines
+                var startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
+                var endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
+                var parts;
+                if (startLine === endLine) {
+                    if (!firstLineIsIndented) {
+                        // treat as single line comment
+                        insertIndentation(commentRange.pos, indentation, /*lineAdded*/ false);
+                    }
+                    return;
+                }
+                else {
+                    parts = [];
+                    var startPos = commentRange.pos;
+                    for (var line = startLine; line < endLine; line++) {
+                        var endOfLine = ts.getEndLinePosition(line, sourceFile);
+                        parts.push({ pos: startPos, end: endOfLine });
+                        startPos = ts.getStartPositionOfLine(line + 1, sourceFile);
+                    }
+                    parts.push({ pos: startPos, end: commentRange.end });
+                }
+                var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
+                var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options);
+                if (indentation === nonWhitespaceColumnInFirstPart.column) {
+                    return;
+                }
+                var startIndex = 0;
+                if (firstLineIsIndented) {
+                    startIndex = 1;
+                    startLine++;
+                }
+                // shift all parts on the delta size
+                var delta = indentation - nonWhitespaceColumnInFirstPart.column;
+                for (var i = startIndex; i < parts.length; i++, startLine++) {
+                    var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile);
+                    var nonWhitespaceCharacterAndColumn = i === 0
+                        ? nonWhitespaceColumnInFirstPart
+                        : formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options);
+                    var newIndentation = nonWhitespaceCharacterAndColumn.column + delta;
+                    if (newIndentation > 0) {
+                        var indentationString = getIndentationString(newIndentation, options);
+                        recordReplace(startLinePos_1, nonWhitespaceCharacterAndColumn.character, indentationString);
+                    }
+                    else {
+                        recordDelete(startLinePos_1, nonWhitespaceCharacterAndColumn.character);
+                    }
+                }
+            }
+            function trimTrailingWhitespacesForLines(line1, line2, range) {
+                for (var line = line1; line < line2; line++) {
+                    var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
+                    var lineEndPosition = ts.getEndLinePosition(line, sourceFile);
+                    // do not trim whitespaces in comments or template expression
+                    if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
+                        continue;
+                    }
+                    var whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition);
+                    if (whitespaceStart !== -1) {
+                        ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1)));
+                        recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart);
+                    }
+                }
+            }
+            /**
+             * @param start The position of the first character in range
+             * @param end The position of the last character in range
+             */
+            function getTrailingWhitespaceStartPosition(start, end) {
+                var pos = end;
+                while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) {
+                    pos--;
+                }
+                if (pos !== end) {
+                    return pos + 1;
+                }
+                return -1;
+            }
+            /**
+             * Trimming will be done for lines after the previous range
+             */
+            function trimTrailingWhitespacesForRemainingRange() {
+                var startPosition = previousRange ? previousRange.end : originalRange.pos;
+                var startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line;
+                var endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line;
+                trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange);
+            }
+            function newTextChange(start, len, newText) {
+                return { span: ts.createTextSpan(start, len), newText: newText };
+            }
+            function recordDelete(start, len) {
+                if (len) {
+                    edits.push(newTextChange(start, len, ""));
+                }
+            }
+            function recordReplace(start, len, newText) {
+                if (len || newText) {
+                    edits.push(newTextChange(start, len, newText));
+                }
+            }
+            function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) {
+                switch (rule.Operation.Action) {
+                    case 1 /* Ignore */:
+                        // no action required
+                        return;
+                    case 8 /* Delete */:
+                        if (previousRange.end !== currentRange.pos) {
+                            // delete characters starting from t1.end up to t2.pos exclusive
+                            recordDelete(previousRange.end, currentRange.pos - previousRange.end);
+                        }
+                        break;
+                    case 4 /* NewLine */:
+                        // exit early if we on different lines and rule cannot change number of newlines
+                        // if line1 and line2 are on subsequent lines then no edits are required - ok to exit
+                        // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
+                        if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
+                            return;
+                        }
+                        // edit should not be applied if we have one line feed between elements
+                        var lineDelta = currentStartLine - previousStartLine;
+                        if (lineDelta !== 1) {
+                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter);
+                        }
+                        break;
+                    case 2 /* Space */:
+                        // exit early if we on different lines and rule cannot change number of newlines
+                        if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
+                            return;
+                        }
+                        var posDelta = currentRange.pos - previousRange.end;
+                        if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== 32 /* space */) {
+                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
+                        }
+                        break;
+                }
+            }
+        }
+        /**
+         * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`.
+         */
+        function getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine, precedingToken, // tslint:disable-line:no-null-keyword
+            tokenAtPosition, predicate) {
+            if (tokenAtPosition === void 0) { tokenAtPosition = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); }
+            var tokenStart = tokenAtPosition.getStart(sourceFile);
+            if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
+                return undefined;
+            }
+            if (precedingToken === undefined) {
+                precedingToken = ts.findPrecedingToken(position, sourceFile);
+            }
+            // Between two consecutive tokens, all comments are either trailing on the former
+            // or leading on the latter (and none are in both lists).
+            var trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end);
+            var leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile);
+            var commentRanges = trailingRangesOfPreviousToken && leadingCommentRangesOfNextToken ?
+                trailingRangesOfPreviousToken.concat(leadingCommentRangesOfNextToken) :
+                trailingRangesOfPreviousToken || leadingCommentRangesOfNextToken;
+            if (commentRanges) {
+                for (var _i = 0, commentRanges_1 = commentRanges; _i < commentRanges_1.length; _i++) {
+                    var range = commentRanges_1[_i];
+                    // The end marker of a single-line comment does not include the newline character.
+                    // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
+                    //
+                    //    // asdf   ^\n
+                    //
+                    // But for closed multi-line comments, we don't want to be inside the comment in the following case:
+                    //
+                    //    /* asdf */^
+                    //
+                    // However, unterminated multi-line comments *do* contain their end.
+                    //
+                    // Internally, we represent the end of the comment at the newline and closing '/', respectively.
+                    //
+                    if ((range.pos < position && position < range.end ||
+                        position === range.end && (range.kind === 2 /* SingleLineCommentTrivia */ || position === sourceFile.getFullWidth()))) {
+                        return (range.kind === 3 /* MultiLineCommentTrivia */ || !onlyMultiLine) && (!predicate || predicate(range)) ? range : undefined;
+                    }
+                }
+            }
+            return undefined;
+        }
+        formatting.getRangeOfEnclosingComment = getRangeOfEnclosingComment;
+        function getOpenTokenForList(node, list) {
+            switch (node.kind) {
+                case 152 /* Constructor */:
+                case 228 /* FunctionDeclaration */:
+                case 186 /* FunctionExpression */:
+                case 151 /* MethodDeclaration */:
+                case 150 /* MethodSignature */:
+                case 187 /* ArrowFunction */:
+                    if (node.typeParameters === list) {
+                        return 27 /* LessThanToken */;
+                    }
+                    else if (node.parameters === list) {
+                        return 19 /* OpenParenToken */;
+                    }
+                    break;
+                case 181 /* CallExpression */:
+                case 182 /* NewExpression */:
+                    if (node.typeArguments === list) {
+                        return 27 /* LessThanToken */;
+                    }
+                    else if (node.arguments === list) {
+                        return 19 /* OpenParenToken */;
+                    }
+                    break;
+                case 159 /* TypeReference */:
+                    if (node.typeArguments === list) {
+                        return 27 /* LessThanToken */;
+                    }
+            }
+            return 0 /* Unknown */;
+        }
+        function getCloseTokenForOpenToken(kind) {
+            switch (kind) {
+                case 19 /* OpenParenToken */:
+                    return 20 /* CloseParenToken */;
+                case 27 /* LessThanToken */:
+                    return 29 /* GreaterThanToken */;
+            }
+            return 0 /* Unknown */;
+        }
+        var internedSizes;
+        var internedTabsIndentation;
+        var internedSpacesIndentation;
+        function getIndentationString(indentation, options) {
+            // reset interned strings if FormatCodeOptions were changed
+            var resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize);
+            if (resetInternedStrings) {
+                internedSizes = { tabSize: options.tabSize, indentSize: options.indentSize };
+                internedTabsIndentation = internedSpacesIndentation = undefined;
+            }
+            if (!options.convertTabsToSpaces) {
+                var tabs = Math.floor(indentation / options.tabSize);
+                var spaces = indentation - tabs * options.tabSize;
+                var tabString = void 0;
+                if (!internedTabsIndentation) {
+                    internedTabsIndentation = [];
+                }
+                if (internedTabsIndentation[tabs] === undefined) {
+                    internedTabsIndentation[tabs] = tabString = repeat("\t", tabs);
+                }
+                else {
+                    tabString = internedTabsIndentation[tabs];
+                }
+                return spaces ? tabString + repeat(" ", spaces) : tabString;
+            }
+            else {
+                var spacesString = void 0;
+                var quotient = Math.floor(indentation / options.indentSize);
+                var remainder = indentation % options.indentSize;
+                if (!internedSpacesIndentation) {
+                    internedSpacesIndentation = [];
+                }
+                if (internedSpacesIndentation[quotient] === undefined) {
+                    spacesString = repeat(" ", options.indentSize * quotient);
+                    internedSpacesIndentation[quotient] = spacesString;
+                }
+                else {
+                    spacesString = internedSpacesIndentation[quotient];
+                }
+                return remainder ? spacesString + repeat(" ", remainder) : spacesString;
+            }
+            function repeat(value, count) {
+                var s = "";
+                for (var i = 0; i < count; i++) {
+                    s += value;
+                }
+                return s;
+            }
+        }
+        formatting.getIndentationString = getIndentationString;
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+///<reference path='..\services.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var formatting;
+    (function (formatting) {
+        var SmartIndenter;
+        (function (SmartIndenter) {
+            var Value;
+            (function (Value) {
+                Value[Value["Unknown"] = -1] = "Unknown";
+            })(Value || (Value = {}));
+            /**
+             * @param assumeNewLineBeforeCloseBrace
+             * `false` when called on text from a real source file.
+             * `true` when we need to assume `position` is on a newline.
+             *
+             * This is useful for codefixes. Consider
+             * ```
+             * function f() {
+             * |}
+             * ```
+             * with `position` at `|`.
+             *
+             * When inserting some text after an open brace, we would like to get indentation as if a newline was already there.
+             * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior.
+             */
+            function getIndentation(position, sourceFile, options, assumeNewLineBeforeCloseBrace) {
+                if (assumeNewLineBeforeCloseBrace === void 0) { assumeNewLineBeforeCloseBrace = false; }
+                if (position > sourceFile.text.length) {
+                    return getBaseIndentation(options); // past EOF
+                }
+                // no indentation when the indent style is set to none,
+                // so we can return fast
+                if (options.indentStyle === ts.IndentStyle.None) {
+                    return 0;
+                }
+                var precedingToken = ts.findPrecedingToken(position, sourceFile);
+                var enclosingCommentRange = formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ true, precedingToken || null); // tslint:disable-line:no-null-keyword
+                if (enclosingCommentRange) {
+                    var previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1;
+                    var commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line;
+                    ts.Debug.assert(commentStartLine >= 0);
+                    if (previousLine <= commentStartLine) {
+                        return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options);
+                    }
+                    var startPostionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile);
+                    var _a = findFirstNonWhitespaceCharacterAndColumn(startPostionOfLine, position, sourceFile, options), column = _a.column, character = _a.character;
+                    if (column === 0) {
+                        return column;
+                    }
+                    var firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPostionOfLine + character);
+                    return firstNonWhitespaceCharacterCode === 42 /* asterisk */ ? column - 1 : column;
+                }
+                if (!precedingToken) {
+                    return getBaseIndentation(options);
+                }
+                // no indentation in string \regex\template literals
+                var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
+                if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) {
+                    return 0;
+                }
+                var lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
+                // indentation is first non-whitespace character in a previous line
+                // for block indentation, we should look for a line which contains something that's not
+                // whitespace.
+                if (options.indentStyle === ts.IndentStyle.Block) {
+                    // move backwards until we find a line with a non-whitespace character,
+                    // then find the first non-whitespace character for that line.
+                    var current_1 = position;
+                    while (current_1 > 0) {
+                        var char = sourceFile.text.charCodeAt(current_1);
+                        if (!ts.isWhiteSpaceLike(char)) {
+                            break;
+                        }
+                        current_1--;
+                    }
+                    var lineStart = ts.getLineStartPositionForPosition(current_1, sourceFile);
+                    return SmartIndenter.findFirstNonWhitespaceColumn(lineStart, current_1, sourceFile, options);
+                }
+                if (precedingToken.kind === 26 /* CommaToken */ && precedingToken.parent.kind !== 194 /* BinaryExpression */) {
+                    // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
+                    var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
+                    if (actualIndentation !== -1 /* Unknown */) {
+                        return actualIndentation;
+                    }
+                }
+                // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken'
+                // if such node is found - compute initial indentation for 'position' inside this node
+                var previous;
+                var current = precedingToken;
+                var currentStart;
+                var indentationDelta;
+                while (current) {
+                    if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous)) {
+                        currentStart = getStartLineAndCharacterForNode(current, sourceFile);
+                        var nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile);
+                        if (nextTokenKind !== 0 /* Unknown */) {
+                            // handle cases when codefix is about to be inserted before the close brace
+                            indentationDelta = assumeNewLineBeforeCloseBrace && nextTokenKind === 2 /* CloseBrace */ ? options.indentSize : 0;
+                        }
+                        else {
+                            indentationDelta = lineAtPosition !== currentStart.line ? options.indentSize : 0;
+                        }
+                        break;
+                    }
+                    // check if current node is a list item - if yes, take indentation from it
+                    var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
+                    if (actualIndentation !== -1 /* Unknown */) {
+                        return actualIndentation;
+                    }
+                    actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options);
+                    if (actualIndentation !== -1 /* Unknown */) {
+                        return actualIndentation + options.indentSize;
+                    }
+                    previous = current;
+                    current = current.parent;
+                }
+                if (!current) {
+                    // no parent was found - return the base indentation of the SourceFile
+                    return getBaseIndentation(options);
+                }
+                return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, options);
+            }
+            SmartIndenter.getIndentation = getIndentation;
+            function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) {
+                var start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
+                return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, options);
+            }
+            SmartIndenter.getIndentationForNode = getIndentationForNode;
+            function getBaseIndentation(options) {
+                return options.baseIndentSize || 0;
+            }
+            SmartIndenter.getBaseIndentation = getBaseIndentation;
+            function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, options) {
+                var parent = current.parent;
+                var containingListOrParentStart;
+                // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if
+                // * parent and child nodes start on the same line, or
+                // * parent is an IfStatement and child starts on the same line as an 'else clause'.
+                while (parent) {
+                    var useActualIndentation = true;
+                    if (ignoreActualIndentationRange) {
+                        var start = current.getStart(sourceFile);
+                        useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
+                    }
+                    if (useActualIndentation) {
+                        // check if current node is a list item - if yes, take indentation from it
+                        var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
+                        if (actualIndentation !== -1 /* Unknown */) {
+                            return actualIndentation + indentationDelta;
+                        }
+                    }
+                    containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile);
+                    var parentAndChildShareLine = containingListOrParentStart.line === currentStart.line ||
+                        childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
+                    if (useActualIndentation) {
+                        // try to fetch actual indentation for current node from source text
+                        var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
+                        if (actualIndentation !== -1 /* Unknown */) {
+                            return actualIndentation + indentationDelta;
+                        }
+                        actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options);
+                        if (actualIndentation !== -1 /* Unknown */) {
+                            return actualIndentation + indentationDelta;
+                        }
+                    }
+                    // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
+                    if (shouldIndentChildNode(parent, current) && !parentAndChildShareLine) {
+                        indentationDelta += options.indentSize;
+                    }
+                    // In our AST, a call argument's `parent` is the call-expression, not the argument list.
+                    // We would like to increase indentation based on the relationship between an argument and its argument-list,
+                    // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list.
+                    // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression
+                    // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation.
+                    //
+                    // Instead, when at an argument, we unspoof the starting position of the enclosing call expression
+                    // *after* applying indentation for the argument.
+                    var useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile);
+                    current = parent;
+                    parent = current.parent;
+                    currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : containingListOrParentStart;
+                }
+                return indentationDelta + getBaseIndentation(options);
+            }
+            function getContainingListOrParentStart(parent, child, sourceFile) {
+                var containingList = getContainingList(child, sourceFile);
+                var startPos = containingList ? containingList.pos : parent.getStart(sourceFile);
+                return sourceFile.getLineAndCharacterOfPosition(startPos);
+            }
+            /*
+             * Function returns Value.Unknown if indentation cannot be determined
+             */
+            function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) {
+                // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
+                var commaItemInfo = ts.findListItemInfo(commaToken);
+                if (commaItemInfo && commaItemInfo.listItemIndex > 0) {
+                    return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
+                }
+                else {
+                    // handle broken code gracefully
+                    return -1 /* Unknown */;
+                }
+            }
+            /*
+             * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression)
+             */
+            function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) {
+                // actual indentation is used for statements\declarations if one of cases below is true:
+                // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
+                // - parent and child are not on the same line
+                var useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) &&
+                    (parent.kind === 265 /* SourceFile */ || !parentAndChildShareLine);
+                if (!useActualIndentation) {
+                    return -1 /* Unknown */;
+                }
+                return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
+            }
+            var NextTokenKind;
+            (function (NextTokenKind) {
+                NextTokenKind[NextTokenKind["Unknown"] = 0] = "Unknown";
+                NextTokenKind[NextTokenKind["OpenBrace"] = 1] = "OpenBrace";
+                NextTokenKind[NextTokenKind["CloseBrace"] = 2] = "CloseBrace";
+            })(NextTokenKind || (NextTokenKind = {}));
+            function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
+                var nextToken = ts.findNextToken(precedingToken, current);
+                if (!nextToken) {
+                    return 0 /* Unknown */;
+                }
+                if (nextToken.kind === 17 /* OpenBraceToken */) {
+                    // open braces are always indented at the parent level
+                    return 1 /* OpenBrace */;
+                }
+                else if (nextToken.kind === 18 /* CloseBraceToken */) {
+                    // close braces are indented at the parent level if they are located on the same line with cursor
+                    // this means that if new line will be added at $ position, this case will be indented
+                    // class A {
+                    //    $
+                    // }
+                    /// and this one - not
+                    // class A {
+                    // $}
+                    var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
+                    return lineAtPosition === nextTokenStartLine ? 2 /* CloseBrace */ : 0 /* Unknown */;
+                }
+                return 0 /* Unknown */;
+            }
+            function getStartLineAndCharacterForNode(n, sourceFile) {
+                return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
+            }
+            function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, child, childStartLine, sourceFile) {
+                if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) {
+                    return false;
+                }
+                var expressionOfCallExpressionEnd = parent.expression.getEnd();
+                var expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line;
+                return expressionOfCallExpressionEndLine === childStartLine;
+            }
+            SmartIndenter.isArgumentAndStartLineOverlapsExpressionBeingCalled = isArgumentAndStartLineOverlapsExpressionBeingCalled;
+            function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
+                if (parent.kind === 211 /* IfStatement */ && parent.elseStatement === child) {
+                    var elseKeyword = ts.findChildOfKind(parent, 82 /* ElseKeyword */, sourceFile);
+                    ts.Debug.assert(elseKeyword !== undefined);
+                    var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
+                    return elseKeywordStartLine === childStartLine;
+                }
+                return false;
+            }
+            SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
+            function getListIfStartEndIsInListRange(list, start, end) {
+                return list && ts.rangeContainsStartEnd(list, start, end) ? list : undefined;
+            }
+            function getContainingList(node, sourceFile) {
+                if (node.parent) {
+                    switch (node.parent.kind) {
+                        case 159 /* TypeReference */:
+                            return getListIfStartEndIsInListRange(node.parent.typeArguments, node.getStart(sourceFile), node.getEnd());
+                        case 178 /* ObjectLiteralExpression */:
+                            return node.parent.properties;
+                        case 177 /* ArrayLiteralExpression */:
+                            return node.parent.elements;
+                        case 228 /* FunctionDeclaration */:
+                        case 186 /* FunctionExpression */:
+                        case 187 /* ArrowFunction */:
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 155 /* CallSignature */:
+                        case 152 /* Constructor */:
+                        case 161 /* ConstructorType */:
+                        case 156 /* ConstructSignature */: {
+                            var start = node.getStart(sourceFile);
+                            return getListIfStartEndIsInListRange(node.parent.typeParameters, start, node.getEnd()) ||
+                                getListIfStartEndIsInListRange(node.parent.parameters, start, node.getEnd());
+                        }
+                        case 229 /* ClassDeclaration */:
+                            return getListIfStartEndIsInListRange(node.parent.typeParameters, node.getStart(sourceFile), node.getEnd());
+                        case 182 /* NewExpression */:
+                        case 181 /* CallExpression */: {
+                            var start = node.getStart(sourceFile);
+                            return getListIfStartEndIsInListRange(node.parent.typeArguments, start, node.getEnd()) ||
+                                getListIfStartEndIsInListRange(node.parent.arguments, start, node.getEnd());
+                        }
+                        case 227 /* VariableDeclarationList */:
+                            return getListIfStartEndIsInListRange(node.parent.declarations, node.getStart(sourceFile), node.getEnd());
+                        case 241 /* NamedImports */:
+                        case 245 /* NamedExports */:
+                            return getListIfStartEndIsInListRange(node.parent.elements, node.getStart(sourceFile), node.getEnd());
+                    }
+                }
+                return undefined;
+            }
+            SmartIndenter.getContainingList = getContainingList;
+            function getActualIndentationForListItem(node, sourceFile, options) {
+                var containingList = getContainingList(node, sourceFile);
+                return containingList ? getActualIndentationFromList(containingList) : -1 /* Unknown */;
+                function getActualIndentationFromList(list) {
+                    var index = ts.indexOf(list, node);
+                    return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : -1 /* Unknown */;
+                }
+            }
+            function getLineIndentationWhenExpressionIsInMultiLine(node, sourceFile, options) {
+                // actual indentation should not be used when:
+                // - node is close parenthesis - this is the end of the expression
+                if (node.kind === 20 /* CloseParenToken */) {
+                    return -1 /* Unknown */;
+                }
+                if (node.parent && ts.isCallOrNewExpression(node.parent) && node.parent.expression !== node) {
+                    var fullCallOrNewExpression = node.parent.expression;
+                    var startingExpression = getStartingExpression(fullCallOrNewExpression);
+                    if (fullCallOrNewExpression === startingExpression) {
+                        return -1 /* Unknown */;
+                    }
+                    var fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end);
+                    var startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end);
+                    if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) {
+                        return -1 /* Unknown */;
+                    }
+                    return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options);
+                }
+                return -1 /* Unknown */;
+                function getStartingExpression(node) {
+                    while (true) {
+                        switch (node.kind) {
+                            case 181 /* CallExpression */:
+                            case 182 /* NewExpression */:
+                            case 179 /* PropertyAccessExpression */:
+                            case 180 /* ElementAccessExpression */:
+                                node = node.expression;
+                                break;
+                            default:
+                                return node;
+                        }
+                    }
+                }
+            }
+            function deriveActualIndentationFromList(list, index, sourceFile, options) {
+                ts.Debug.assert(index >= 0 && index < list.length);
+                var node = list[index];
+                // walk toward the start of the list starting from current node and check if the line is the same for all items.
+                // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
+                var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
+                for (var i = index - 1; i >= 0; i--) {
+                    if (list[i].kind === 26 /* CommaToken */) {
+                        continue;
+                    }
+                    // skip list items that ends on the same line with the current list element
+                    var prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line;
+                    if (prevEndLine !== lineAndCharacter.line) {
+                        return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
+                    }
+                    lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
+                }
+                return -1 /* Unknown */;
+            }
+            function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) {
+                var lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0);
+                return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
+            }
+            /**
+             * Character is the actual index of the character since the beginning of the line.
+             * Column - position of the character after expanding tabs to spaces.
+             * "0\t2$"
+             * value of 'character' for '$' is 3
+             * value of 'column' for '$' is 6 (assuming that tab size is 4)
+             */
+            function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) {
+                var character = 0;
+                var column = 0;
+                for (var pos = startPos; pos < endPos; pos++) {
+                    var ch = sourceFile.text.charCodeAt(pos);
+                    if (!ts.isWhiteSpaceSingleLine(ch)) {
+                        break;
+                    }
+                    if (ch === 9 /* tab */) {
+                        column += options.tabSize + (column % options.tabSize);
+                    }
+                    else {
+                        column++;
+                    }
+                    character++;
+                }
+                return { column: column, character: character };
+            }
+            SmartIndenter.findFirstNonWhitespaceCharacterAndColumn = findFirstNonWhitespaceCharacterAndColumn;
+            function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) {
+                return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column;
+            }
+            SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn;
+            function nodeContentIsAlwaysIndented(kind) {
+                switch (kind) {
+                    case 210 /* ExpressionStatement */:
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 177 /* ArrayLiteralExpression */:
+                    case 207 /* Block */:
+                    case 234 /* ModuleBlock */:
+                    case 178 /* ObjectLiteralExpression */:
+                    case 163 /* TypeLiteral */:
+                    case 172 /* MappedType */:
+                    case 165 /* TupleType */:
+                    case 235 /* CaseBlock */:
+                    case 258 /* DefaultClause */:
+                    case 257 /* CaseClause */:
+                    case 185 /* ParenthesizedExpression */:
+                    case 179 /* PropertyAccessExpression */:
+                    case 181 /* CallExpression */:
+                    case 182 /* NewExpression */:
+                    case 208 /* VariableStatement */:
+                    case 226 /* VariableDeclaration */:
+                    case 243 /* ExportAssignment */:
+                    case 219 /* ReturnStatement */:
+                    case 195 /* ConditionalExpression */:
+                    case 175 /* ArrayBindingPattern */:
+                    case 174 /* ObjectBindingPattern */:
+                    case 251 /* JsxOpeningElement */:
+                    case 250 /* JsxSelfClosingElement */:
+                    case 256 /* JsxExpression */:
+                    case 150 /* MethodSignature */:
+                    case 155 /* CallSignature */:
+                    case 156 /* ConstructSignature */:
+                    case 146 /* Parameter */:
+                    case 160 /* FunctionType */:
+                    case 161 /* ConstructorType */:
+                    case 168 /* ParenthesizedType */:
+                    case 183 /* TaggedTemplateExpression */:
+                    case 191 /* AwaitExpression */:
+                    case 245 /* NamedExports */:
+                    case 241 /* NamedImports */:
+                    case 246 /* ExportSpecifier */:
+                    case 242 /* ImportSpecifier */:
+                    case 261 /* PropertyAssignment */:
+                    case 149 /* PropertyDeclaration */:
+                        return true;
+                }
+                return false;
+            }
+            /* @internal */
+            function nodeWillIndentChild(parent, child, indentByDefault) {
+                var childKind = child ? child.kind : 0 /* Unknown */;
+                switch (parent.kind) {
+                    case 212 /* DoStatement */:
+                    case 213 /* WhileStatement */:
+                    case 215 /* ForInStatement */:
+                    case 216 /* ForOfStatement */:
+                    case 214 /* ForStatement */:
+                    case 211 /* IfStatement */:
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                    case 151 /* MethodDeclaration */:
+                    case 187 /* ArrowFunction */:
+                    case 152 /* Constructor */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                        return childKind !== 207 /* Block */;
+                    case 244 /* ExportDeclaration */:
+                        return childKind !== 245 /* NamedExports */;
+                    case 238 /* ImportDeclaration */:
+                        return childKind !== 239 /* ImportClause */ ||
+                            (child.namedBindings && child.namedBindings.kind !== 241 /* NamedImports */);
+                    case 249 /* JsxElement */:
+                        return childKind !== 252 /* JsxClosingElement */;
+                }
+                // No explicit rule for given nodes so the result will follow the default value argument
+                return indentByDefault;
+            }
+            SmartIndenter.nodeWillIndentChild = nodeWillIndentChild;
+            /*
+            Function returns true when the parent node should indent the given child by an explicit rule
+            */
+            function shouldIndentChildNode(parent, child) {
+                return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false);
+            }
+            SmartIndenter.shouldIndentChildNode = shouldIndentChildNode;
+        })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {}));
+    })(formatting = ts.formatting || (ts.formatting = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var textChanges;
+    (function (textChanges) {
+        /**
+         * Currently for simplicity we store recovered positions on the node itself.
+         * It can be changed to side-table later if we decide that current design is too invasive.
+         */
+        function getPos(n) {
+            var result = n.__pos;
+            ts.Debug.assert(typeof result === "number");
+            return result;
+        }
+        function setPos(n, pos) {
+            ts.Debug.assert(typeof pos === "number");
+            n.__pos = pos;
+        }
+        function getEnd(n) {
+            var result = n.__end;
+            ts.Debug.assert(typeof result === "number");
+            return result;
+        }
+        function setEnd(n, end) {
+            ts.Debug.assert(typeof end === "number");
+            n.__end = end;
+        }
+        var Position;
+        (function (Position) {
+            Position[Position["FullStart"] = 0] = "FullStart";
+            Position[Position["Start"] = 1] = "Start";
+        })(Position = textChanges.Position || (textChanges.Position = {}));
+        function skipWhitespacesAndLineBreaks(text, start) {
+            return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
+        }
+        function hasCommentsBeforeLineBreak(text, start) {
+            var i = start;
+            while (i < text.length) {
+                var ch = text.charCodeAt(i);
+                if (ts.isWhiteSpaceSingleLine(ch)) {
+                    i++;
+                    continue;
+                }
+                return ch === 47 /* slash */;
+            }
+            return false;
+        }
+        var ChangeKind;
+        (function (ChangeKind) {
+            ChangeKind[ChangeKind["Remove"] = 0] = "Remove";
+            ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode";
+            ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes";
+        })(ChangeKind || (ChangeKind = {}));
+        function getSeparatorCharacter(separator) {
+            return ts.tokenToString(separator.kind);
+        }
+        textChanges.getSeparatorCharacter = getSeparatorCharacter;
+        function getAdjustedStartPosition(sourceFile, node, options, position) {
+            if (options.useNonAdjustedStartPosition) {
+                return node.getFullStart();
+            }
+            var fullStart = node.getFullStart();
+            var start = node.getStart(sourceFile);
+            if (fullStart === start) {
+                return start;
+            }
+            var fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile);
+            var startLine = ts.getLineStartPositionForPosition(start, sourceFile);
+            if (startLine === fullStartLine) {
+                // full start and start of the node are on the same line
+                //   a,     b;
+                //    ^     ^
+                //    |   start
+                // fullstart
+                // when b is replaced - we usually want to keep the leading trvia
+                // when b is deleted - we delete it
+                return position === Position.Start ? start : fullStart;
+            }
+            // get start position of the line following the line that contains fullstart position
+            // (but only if the fullstart isn't the very beginning of the file)
+            var nextLineStart = fullStart > 0 ? 1 : 0;
+            var adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile);
+            // skip whitespaces/newlines
+            adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition);
+            return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile);
+        }
+        textChanges.getAdjustedStartPosition = getAdjustedStartPosition;
+        function getAdjustedEndPosition(sourceFile, node, options) {
+            if (options.useNonAdjustedEndPosition || ts.isExpression(node)) {
+                return node.getEnd();
+            }
+            var end = node.getEnd();
+            var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
+            return newEnd !== end && ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1))
+                ? newEnd
+                : end;
+        }
+        textChanges.getAdjustedEndPosition = getAdjustedEndPosition;
+        /**
+         * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element
+         */
+        function isSeparator(node, candidate) {
+            return candidate && node.parent && (candidate.kind === 26 /* CommaToken */ || (candidate.kind === 25 /* SemicolonToken */ && node.parent.kind === 178 /* ObjectLiteralExpression */));
+        }
+        function spaces(count) {
+            var s = "";
+            for (var i = 0; i < count; i++) {
+                s += " ";
+            }
+            return s;
+        }
+        var ChangeTracker = /** @class */ (function () {
+            function ChangeTracker(newLine, rulesProvider, validator) {
+                this.newLine = newLine;
+                this.rulesProvider = rulesProvider;
+                this.validator = validator;
+                this.changes = [];
+                this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine });
+            }
+            ChangeTracker.fromContext = function (context) {
+                return new ChangeTracker(context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */, context.rulesProvider);
+            };
+            ChangeTracker.with = function (context, cb) {
+                var tracker = ChangeTracker.fromContext(context);
+                cb(tracker);
+                return tracker.getChanges();
+            };
+            ChangeTracker.prototype.deleteRange = function (sourceFile, range) {
+                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range });
+                return this;
+            };
+            ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) {
+                if (options === void 0) { options = {}; }
+                var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart);
+                var endPosition = getAdjustedEndPosition(sourceFile, node, options);
+                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } });
+                return this;
+            };
+            ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) {
+                if (options === void 0) { options = {}; }
+                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart);
+                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
+                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } });
+                return this;
+            };
+            ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) {
+                var containingList = ts.formatting.SmartIndenter.getContainingList(node, sourceFile);
+                if (!containingList) {
+                    ts.Debug.fail("node is not a list element");
+                    return this;
+                }
+                var index = ts.indexOfNode(containingList, node);
+                if (index < 0) {
+                    return this;
+                }
+                if (containingList.length === 1) {
+                    this.deleteNode(sourceFile, node);
+                    return this;
+                }
+                if (index !== containingList.length - 1) {
+                    var nextToken = ts.getTokenAtPosition(sourceFile, node.end, /*includeJsDocComment*/ false);
+                    if (nextToken && isSeparator(node, nextToken)) {
+                        // find first non-whitespace position in the leading trivia of the node
+                        var startPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
+                        var nextElement = containingList[index + 1];
+                        /// find first non-whitespace position in the leading trivia of the next node
+                        var endPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
+                        // shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node
+                        this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
+                    }
+                }
+                else {
+                    var previousToken = ts.getTokenAtPosition(sourceFile, containingList[index - 1].end, /*includeJsDocComment*/ false);
+                    if (previousToken && isSeparator(node, previousToken)) {
+                        this.deleteNodeRange(sourceFile, previousToken, node);
+                    }
+                }
+                return this;
+            };
+            ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) {
+                if (options === void 0) { options = {}; }
+                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode });
+                return this;
+            };
+            ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) {
+                if (options === void 0) { options = {}; }
+                var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start);
+                var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options);
+                return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options);
+            };
+            ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) {
+                if (options === void 0) { options = {}; }
+                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start);
+                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
+                return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options);
+            };
+            ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) {
+                this.changes.push({
+                    kind: ChangeKind.ReplaceWithSingleNode,
+                    sourceFile: sourceFile,
+                    options: options,
+                    node: newNode,
+                    range: { pos: startPosition, end: endPosition }
+                });
+                return this;
+            };
+            ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) {
+                this.changes.push({
+                    kind: ChangeKind.ReplaceWithMultipleNodes,
+                    sourceFile: sourceFile,
+                    options: options,
+                    nodes: newNodes,
+                    range: { pos: startPosition, end: endPosition }
+                });
+                return this;
+            };
+            ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) {
+                var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start);
+                var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options);
+                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
+            };
+            ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) {
+                var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start);
+                var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options);
+                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
+            };
+            ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) {
+                return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options);
+            };
+            ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) {
+                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start);
+                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
+                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
+            };
+            ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) {
+                if (options === void 0) { options = {}; }
+                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } });
+                return this;
+            };
+            ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) {
+                if (options === void 0) { options = {}; }
+                var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start);
+                return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options);
+            };
+            ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) {
+                if (options === void 0) { options = {}; }
+                if ((ts.isStatementButNotDeclaration(after)) ||
+                    after.kind === 149 /* PropertyDeclaration */ ||
+                    after.kind === 148 /* PropertySignature */ ||
+                    after.kind === 150 /* MethodSignature */) {
+                    // check if previous statement ends with semicolon
+                    // if not - insert semicolon to preserve the code from changing the meaning due to ASI
+                    if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) {
+                        this.changes.push({
+                            kind: ChangeKind.ReplaceWithSingleNode,
+                            sourceFile: sourceFile,
+                            options: {},
+                            range: { pos: after.end, end: after.end },
+                            node: ts.createToken(25 /* SemicolonToken */)
+                        });
+                    }
+                }
+                var endPosition = getAdjustedEndPosition(sourceFile, after, options);
+                return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options);
+            };
+            /**
+             * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
+             * i.e. arguments in arguments lists, parameters in parameter lists etc.
+             * Note that separators are part of the node in statements and class elements.
+             */
+            ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode) {
+                var containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile);
+                if (!containingList) {
+                    ts.Debug.fail("node is not a list element");
+                    return this;
+                }
+                var index = ts.indexOfNode(containingList, after);
+                if (index < 0) {
+                    return this;
+                }
+                var end = after.getEnd();
+                if (index !== containingList.length - 1) {
+                    // any element except the last one
+                    // use next sibling as an anchor
+                    var nextToken = ts.getTokenAtPosition(sourceFile, after.end, /*includeJsDocComment*/ false);
+                    if (nextToken && isSeparator(after, nextToken)) {
+                        // for list
+                        // a, b, c
+                        // create change for adding 'e' after 'a' as
+                        // - find start of next element after a (it is b)
+                        // - use this start as start and end position in final change
+                        // - build text of change by formatting the text of node + separator + whitespace trivia of b
+                        // in multiline case it will work as
+                        //   a,
+                        //   b,
+                        //   c,
+                        // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#')
+                        //   a,*
+                        // ***insertedtext<separator>#
+                        // ###b,
+                        //   c,
+                        // find line and character of the next element
+                        var lineAndCharOfNextElement = ts.getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart()));
+                        // find line and character of the token that precedes next element (usually it is separator)
+                        var lineAndCharOfNextToken = ts.getLineAndCharacterOfPosition(sourceFile, nextToken.end);
+                        var prefix = void 0;
+                        var startPos = void 0;
+                        if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) {
+                            // next element is located on the same line with separator:
+                            // a,$$$$b
+                            //  ^    ^
+                            //  |    |-next element
+                            //  |-separator
+                            // where $$$ is some leading trivia
+                            // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces
+                            // a,    x,$$$$b
+                            //  ^    ^     ^
+                            //  |    |     |-next element
+                            //  |    |-new inserted node padded with spaces
+                            //  |-separator
+                            startPos = nextToken.end;
+                            prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character);
+                        }
+                        else {
+                            // next element is located on different line that separator
+                            // let insert position be the beginning of the line that contains next element
+                            startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile);
+                        }
+                        this.changes.push({
+                            kind: ChangeKind.ReplaceWithSingleNode,
+                            sourceFile: sourceFile,
+                            range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) },
+                            node: newNode,
+                            options: {
+                                prefix: prefix,
+                                // write separator and leading trivia of the next element as suffix
+                                suffix: "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile))
+                            }
+                        });
+                    }
+                }
+                else {
+                    var afterStart = after.getStart(sourceFile);
+                    var afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile);
+                    var separator = void 0;
+                    var multilineList = false;
+                    // insert element after the last element in the list that has more than one item
+                    // pick the element preceding the after element to:
+                    // - pick the separator
+                    // - determine if list is a multiline
+                    if (containingList.length === 1) {
+                        // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise
+                        // i.e. var x = 1 // this is x
+                        //     | new element will be inserted at this position
+                        separator = 26 /* CommaToken */;
+                    }
+                    else {
+                        // element has more than one element, pick separator from the list
+                        var tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile);
+                        separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : 26 /* CommaToken */;
+                        // determine if list is multiline by checking lines of after element and element that precedes it.
+                        var afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile);
+                        multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition;
+                    }
+                    if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) {
+                        // in this case we'll always treat containing list as multiline
+                        multilineList = true;
+                    }
+                    if (multilineList) {
+                        // insert separator immediately following the 'after' node to preserve comments in trailing trivia
+                        this.changes.push({
+                            kind: ChangeKind.ReplaceWithSingleNode,
+                            sourceFile: sourceFile,
+                            range: { pos: end, end: end },
+                            node: ts.createToken(separator),
+                            options: {}
+                        });
+                        // use the same indentation as 'after' item
+                        var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.rulesProvider.getFormatOptions());
+                        // insert element before the line break on the line that contains 'after' element
+                        var insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false);
+                        if (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
+                            insertPos--;
+                        }
+                        this.changes.push({
+                            kind: ChangeKind.ReplaceWithSingleNode,
+                            sourceFile: sourceFile,
+                            range: { pos: insertPos, end: insertPos },
+                            node: newNode,
+                            options: { indentation: indentation, prefix: this.newLineCharacter }
+                        });
+                    }
+                    else {
+                        this.changes.push({
+                            kind: ChangeKind.ReplaceWithSingleNode,
+                            sourceFile: sourceFile,
+                            range: { pos: end, end: end },
+                            node: newNode,
+                            options: { prefix: ts.tokenToString(separator) + " " }
+                        });
+                    }
+                }
+                return this;
+            };
+            ChangeTracker.prototype.getChanges = function () {
+                var _this = this;
+                var changesPerFile = ts.createMap();
+                // group changes per file
+                for (var _i = 0, _a = this.changes; _i < _a.length; _i++) {
+                    var c = _a[_i];
+                    var changesInFile = changesPerFile.get(c.sourceFile.path);
+                    if (!changesInFile) {
+                        changesPerFile.set(c.sourceFile.path, changesInFile = []);
+                    }
+                    changesInFile.push(c);
+                }
+                // convert changes
+                var fileChangesList = [];
+                changesPerFile.forEach(function (changesInFile) {
+                    var sourceFile = changesInFile[0].sourceFile;
+                    var fileTextChanges = { fileName: sourceFile.fileName, textChanges: [] };
+                    for (var _i = 0, _a = ChangeTracker.normalize(changesInFile); _i < _a.length; _i++) {
+                        var c = _a[_i];
+                        fileTextChanges.textChanges.push({
+                            span: _this.computeSpan(c, sourceFile),
+                            newText: _this.computeNewText(c, sourceFile)
+                        });
+                    }
+                    fileChangesList.push(fileTextChanges);
+                });
+                return fileChangesList;
+            };
+            ChangeTracker.prototype.computeSpan = function (change, _sourceFile) {
+                return ts.createTextSpanFromBounds(change.range.pos, change.range.end);
+            };
+            ChangeTracker.prototype.computeNewText = function (change, sourceFile) {
+                var _this = this;
+                if (change.kind === ChangeKind.Remove) {
+                    // deletion case
+                    return "";
+                }
+                var options = change.options || {};
+                var text;
+                var pos = change.range.pos;
+                var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos;
+                if (change.kind === ChangeKind.ReplaceWithMultipleNodes) {
+                    var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); });
+                    text = parts.join(change.options.nodeSeparator);
+                }
+                else {
+                    ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode");
+                    text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options);
+                }
+                // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line
+                text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, "");
+                return (options.prefix || "") + text + (options.suffix || "");
+            };
+            ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) {
+                var nonformattedText = getNonformattedText(node, sourceFile, this.newLine);
+                if (this.validator) {
+                    this.validator(nonformattedText);
+                }
+                var formatOptions = this.rulesProvider.getFormatOptions();
+                var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos;
+                var initialIndentation = options.indentation !== undefined
+                    ? options.indentation
+                    : (options.useIndentationFromFile !== false)
+                        ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter))
+                        : 0;
+                var delta = options.delta !== undefined
+                    ? options.delta
+                    : ts.formatting.SmartIndenter.shouldIndentChildNode(node)
+                        ? (formatOptions.indentSize || 0)
+                        : 0;
+                return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider);
+            };
+            ChangeTracker.normalize = function (changes) {
+                // order changes by start position
+                var normalized = ts.stableSort(changes, function (a, b) { return a.range.pos - b.range.pos; });
+                // verify that change intervals do not overlap, except possibly at end points.
+                for (var i = 0; i < normalized.length - 2; i++) {
+                    ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos);
+                }
+                return normalized;
+            };
+            return ChangeTracker;
+        }());
+        textChanges.ChangeTracker = ChangeTracker;
+        function getNonformattedText(node, sourceFile, newLine) {
+            var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion };
+            var writer = new Writer(ts.getNewLineCharacter(options));
+            var printer = ts.createPrinter(options, writer);
+            printer.writeNode(4 /* Unspecified */, node, sourceFile, writer);
+            return { text: writer.getText(), node: assignPositionsToNode(node) };
+        }
+        function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) {
+            var lineMap = ts.computeLineStarts(nonFormattedText.text);
+            var file = {
+                text: nonFormattedText.text,
+                lineMap: lineMap,
+                getLineAndCharacterOfPosition: function (pos) { return ts.computeLineAndCharacterOfPosition(lineMap, pos); }
+            };
+            var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider);
+            return applyChanges(nonFormattedText.text, changes);
+        }
+        function applyChanges(text, changes) {
+            for (var i = changes.length - 1; i >= 0; i--) {
+                var change = changes[i];
+                text = "" + text.substring(0, change.span.start) + change.newText + text.substring(ts.textSpanEnd(change.span));
+            }
+            return text;
+        }
+        textChanges.applyChanges = applyChanges;
+        function isTrivia(s) {
+            return ts.skipTrivia(s, 0) === s.length;
+        }
+        function assignPositionsToNode(node) {
+            var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode);
+            // create proxy node for non synthesized nodes
+            var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited);
+            newNode.pos = getPos(node);
+            newNode.end = getEnd(node);
+            return newNode;
+        }
+        function assignPositionsToNodeArray(nodes, visitor, test, start, count) {
+            var visited = ts.visitNodes(nodes, visitor, test, start, count);
+            if (!visited) {
+                return visited;
+            }
+            // clone nodearray if necessary
+            var nodeArray = visited === nodes ? ts.createNodeArray(visited.slice(0)) : visited;
+            nodeArray.pos = getPos(nodes);
+            nodeArray.end = getEnd(nodes);
+            return nodeArray;
+        }
+        var Writer = /** @class */ (function () {
+            function Writer(newLine) {
+                var _this = this;
+                this.lastNonTriviaPosition = 0;
+                this.writer = ts.createTextWriter(newLine);
+                this.onEmitNode = function (hint, node, printCallback) {
+                    if (node) {
+                        setPos(node, _this.lastNonTriviaPosition);
+                    }
+                    printCallback(hint, node);
+                    if (node) {
+                        setEnd(node, _this.lastNonTriviaPosition);
+                    }
+                };
+                this.onBeforeEmitNodeArray = function (nodes) {
+                    if (nodes) {
+                        setPos(nodes, _this.lastNonTriviaPosition);
+                    }
+                };
+                this.onAfterEmitNodeArray = function (nodes) {
+                    if (nodes) {
+                        setEnd(nodes, _this.lastNonTriviaPosition);
+                    }
+                };
+                this.onBeforeEmitToken = function (node) {
+                    if (node) {
+                        setPos(node, _this.lastNonTriviaPosition);
+                    }
+                };
+                this.onAfterEmitToken = function (node) {
+                    if (node) {
+                        setEnd(node, _this.lastNonTriviaPosition);
+                    }
+                };
+            }
+            Writer.prototype.setLastNonTriviaPosition = function (s, force) {
+                if (force || !isTrivia(s)) {
+                    this.lastNonTriviaPosition = this.writer.getTextPos();
+                    var i = 0;
+                    while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) {
+                        i++;
+                    }
+                    // trim trailing whitespaces
+                    this.lastNonTriviaPosition -= i;
+                }
+            };
+            Writer.prototype.write = function (s) {
+                this.writer.write(s);
+                this.setLastNonTriviaPosition(s, /*force*/ false);
+            };
+            Writer.prototype.writeTextOfNode = function (text, node) {
+                this.writer.writeTextOfNode(text, node);
+            };
+            Writer.prototype.writeLine = function () {
+                this.writer.writeLine();
+            };
+            Writer.prototype.increaseIndent = function () {
+                this.writer.increaseIndent();
+            };
+            Writer.prototype.decreaseIndent = function () {
+                this.writer.decreaseIndent();
+            };
+            Writer.prototype.getText = function () {
+                return this.writer.getText();
+            };
+            Writer.prototype.rawWrite = function (s) {
+                this.writer.rawWrite(s);
+                this.setLastNonTriviaPosition(s, /*force*/ false);
+            };
+            Writer.prototype.writeLiteral = function (s) {
+                this.writer.writeLiteral(s);
+                this.setLastNonTriviaPosition(s, /*force*/ true);
+            };
+            Writer.prototype.getTextPos = function () {
+                return this.writer.getTextPos();
+            };
+            Writer.prototype.getLine = function () {
+                return this.writer.getLine();
+            };
+            Writer.prototype.getColumn = function () {
+                return this.writer.getColumn();
+            };
+            Writer.prototype.getIndent = function () {
+                return this.writer.getIndent();
+            };
+            Writer.prototype.isAtStartOfLine = function () {
+                return this.writer.isAtStartOfLine();
+            };
+            Writer.prototype.reset = function () {
+                this.writer.reset();
+                this.lastNonTriviaPosition = 0;
+            };
+            return Writer;
+        }());
+    })(textChanges = ts.textChanges || (ts.textChanges = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        var codeFixes = [];
+        function registerCodeFix(codeFix) {
+            ts.forEach(codeFix.errorCodes, function (error) {
+                var fixes = codeFixes[error];
+                if (!fixes) {
+                    fixes = [];
+                    codeFixes[error] = fixes;
+                }
+                fixes.push(codeFix);
+            });
+        }
+        codefix.registerCodeFix = registerCodeFix;
+        function getSupportedErrorCodes() {
+            return Object.keys(codeFixes);
+        }
+        codefix.getSupportedErrorCodes = getSupportedErrorCodes;
+        function getFixes(context) {
+            var fixes = codeFixes[context.errorCode];
+            var allActions = [];
+            ts.forEach(fixes, function (f) {
+                var actions = f.getCodeActions(context);
+                if (actions && actions.length > 0) {
+                    for (var _i = 0, actions_1 = actions; _i < actions_1.length; _i++) {
+                        var action = actions_1[_i];
+                        if (action === undefined) {
+                            context.host.log("Action for error code " + context.errorCode + " added an invalid action entry; please log a bug");
+                        }
+                        else {
+                            allActions.push(action);
+                        }
+                    }
+                }
+            });
+            return allActions;
+        }
+        codefix.getFixes = getFixes;
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var refactor;
+    (function (refactor_1) {
+        // A map with the refactor code as key, the refactor itself as value
+        // e.g.  nonSuggestableRefactors[refactorCode] -> the refactor you want
+        var refactors = ts.createMap();
+        function registerRefactor(refactor) {
+            refactors.set(refactor.name, refactor);
+        }
+        refactor_1.registerRefactor = registerRefactor;
+        function getApplicableRefactors(context) {
+            return ts.flatMapIter(refactors.values(), function (refactor) {
+                return context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context);
+            });
+        }
+        refactor_1.getApplicableRefactors = getApplicableRefactors;
+        function getEditsForRefactor(context, refactorName, actionName) {
+            var refactor = refactors.get(refactorName);
+            return refactor && refactor.getEditsForAction(context, actionName);
+        }
+        refactor_1.getEditsForRefactor = getEditsForRefactor;
+    })(refactor = ts.refactor || (ts.refactor = {}));
+    function getRefactorContextLength(context) {
+        return context.endPosition === undefined ? 0 : context.endPosition - context.startPosition;
+    }
+    ts.getRefactorContextLength = getRefactorContextLength;
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+                var decorator = ts.getAncestor(token, 147 /* Decorator */);
+                ts.Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
+                var replacement = ts.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
+                return [{
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Call_decorator_expression),
+                        changes: changeTracker.getChanges()
+                    }];
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+                var qualifiedName = ts.getAncestor(token, 143 /* QualifiedName */);
+                ts.Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
+                if (!ts.isIdentifier(qualifiedName.left)) {
+                    return undefined;
+                }
+                var leftText = qualifiedName.left.getText(sourceFile);
+                var rightText = qualifiedName.right.getText(sourceFile);
+                var replacement = ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), ts.createLiteralTypeNode(ts.createLiteral(rightText)));
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
+                return [{
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Rewrite_as_the_indexed_access_type_0), [leftText + "[\"" + rightText + "\"]"]),
+                        changes: changeTracker.getChanges()
+                    }];
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code],
+            getCodeActions: getActionForClassLikeIncorrectImplementsInterface
+        });
+        function getActionForClassLikeIncorrectImplementsInterface(context) {
+            var sourceFile = context.sourceFile;
+            var start = context.span.start;
+            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+            var checker = context.program.getTypeChecker();
+            var classDeclaration = ts.getContainingClass(token);
+            if (!classDeclaration) {
+                return undefined;
+            }
+            var openBrace = ts.getOpenBraceOfClassLike(classDeclaration, sourceFile);
+            var classType = checker.getTypeAtLocation(classDeclaration);
+            var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(classDeclaration);
+            var hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, 1 /* Number */);
+            var hasStringIndexSignature = !!checker.getIndexTypeOfType(classType, 0 /* String */);
+            var result = [];
+            for (var _i = 0, implementedTypeNodes_2 = implementedTypeNodes; _i < implementedTypeNodes_2.length; _i++) {
+                var implementedTypeNode = implementedTypeNodes_2[_i];
+                // Note that this is ultimately derived from a map indexed by symbol names,
+                // so duplicates cannot occur.
+                var implementedType = checker.getTypeAtLocation(implementedTypeNode);
+                var implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
+                var nonPrivateMembers = implementedTypeSymbols.filter(function (symbol) { return !(ts.getModifierFlags(symbol.valueDeclaration) & 8 /* Private */); });
+                var newNodes = [];
+                createAndAddMissingIndexSignatureDeclaration(implementedType, 1 /* Number */, hasNumericIndexSignature, newNodes);
+                createAndAddMissingIndexSignatureDeclaration(implementedType, 0 /* String */, hasStringIndexSignature, newNodes);
+                newNodes = newNodes.concat(codefix.createMissingMemberNodes(classDeclaration, nonPrivateMembers, checker));
+                var message = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]);
+                if (newNodes.length > 0) {
+                    pushAction(result, newNodes, message);
+                }
+            }
+            return result;
+            function createAndAddMissingIndexSignatureDeclaration(type, kind, hasIndexSigOfKind, newNodes) {
+                if (hasIndexSigOfKind) {
+                    return;
+                }
+                var indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
+                if (!indexInfoOfKind) {
+                    return;
+                }
+                var newIndexSignatureDeclaration = checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration);
+                newNodes.push(newIndexSignatureDeclaration);
+            }
+            function pushAction(result, newNodes, description) {
+                result.push({ description: description, changes: codefix.newNodesToChanges(newNodes, openBrace, context) });
+            }
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1.code,
+                ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code],
+            getCodeActions: getActionsForAddMissingMember
+        });
+        function getActionsForAddMissingMember(context) {
+            var tokenSourceFile = context.sourceFile;
+            var start = context.span.start;
+            // The identifier of the missing property. eg:
+            // this.missing = 1;
+            //      ^^^^^^^
+            var token = ts.getTokenAtPosition(tokenSourceFile, start, /*includeJsDocComment*/ false);
+            if (token.kind !== 71 /* Identifier */) {
+                return undefined;
+            }
+            if (!ts.isPropertyAccessExpression(token.parent)) {
+                return undefined;
+            }
+            var tokenName = token.getText(tokenSourceFile);
+            var makeStatic = false;
+            var classDeclaration;
+            if (token.parent.expression.kind === 99 /* ThisKeyword */) {
+                var containingClassMemberDeclaration = ts.getThisContainer(token, /*includeArrowFunctions*/ false);
+                if (!ts.isClassElement(containingClassMemberDeclaration)) {
+                    return undefined;
+                }
+                classDeclaration = containingClassMemberDeclaration.parent;
+                // Property accesses on `this` in a static method are accesses of a static member.
+                makeStatic = classDeclaration && ts.hasModifier(containingClassMemberDeclaration, 32 /* Static */);
+            }
+            else {
+                var checker = context.program.getTypeChecker();
+                var leftExpression = token.parent.expression;
+                var leftExpressionType = checker.getTypeAtLocation(leftExpression);
+                if (leftExpressionType.flags & 32768 /* Object */) {
+                    var symbol = leftExpressionType.symbol;
+                    if (symbol.flags & 32 /* Class */) {
+                        classDeclaration = symbol.declarations && symbol.declarations[0];
+                        if (leftExpressionType !== checker.getDeclaredTypeOfSymbol(symbol)) {
+                            // The expression is a class symbol but the type is not the instance-side.
+                            makeStatic = true;
+                        }
+                    }
+                }
+            }
+            if (!classDeclaration || !ts.isClassLike(classDeclaration)) {
+                return undefined;
+            }
+            var classDeclarationSourceFile = ts.getSourceFileOfNode(classDeclaration);
+            var classOpenBrace = ts.getOpenBraceOfClassLike(classDeclaration, classDeclarationSourceFile);
+            return ts.isInJavaScriptFile(classDeclarationSourceFile) ?
+                getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) :
+                getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic);
+            function getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) {
+                var actions;
+                var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ false);
+                if (methodCodeAction) {
+                    actions = [methodCodeAction];
+                }
+                if (makeStatic) {
+                    if (classDeclaration.kind === 199 /* ClassExpression */) {
+                        return actions;
+                    }
+                    var className = classDeclaration.name.getText();
+                    var staticInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier(className), tokenName), ts.createIdentifier("undefined")));
+                    var staticInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                    staticInitializationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classDeclaration, staticInitialization, { prefix: context.newLineCharacter, suffix: context.newLineCharacter });
+                    var initializeStaticAction = {
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_static_property_0), [tokenName]),
+                        changes: staticInitializationChangeTracker.getChanges()
+                    };
+                    (actions || (actions = [])).push(initializeStaticAction);
+                    return actions;
+                }
+                else {
+                    var classConstructor = ts.getFirstConstructorWithBody(classDeclaration);
+                    if (!classConstructor) {
+                        return actions;
+                    }
+                    var propertyInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createThis(), tokenName), ts.createIdentifier("undefined")));
+                    var propertyInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                    propertyInitializationChangeTracker.insertNodeBefore(classDeclarationSourceFile, classConstructor.body.getLastToken(), propertyInitialization, { suffix: context.newLineCharacter });
+                    var initializeAction = {
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_property_0_in_the_constructor), [tokenName]),
+                        changes: propertyInitializationChangeTracker.getChanges()
+                    };
+                    (actions || (actions = [])).push(initializeAction);
+                    return actions;
+                }
+            }
+            function getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic) {
+                var actions;
+                var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ true);
+                if (methodCodeAction) {
+                    actions = [methodCodeAction];
+                }
+                var typeNode;
+                if (token.parent.parent.kind === 194 /* BinaryExpression */) {
+                    var binaryExpression = token.parent.parent;
+                    var otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
+                    var checker = context.program.getTypeChecker();
+                    var widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
+                    typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
+                }
+                typeNode = typeNode || ts.createKeywordTypeNode(119 /* AnyKeyword */);
+                var property = ts.createProperty(
+                /*decorators*/ undefined, 
+                /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, tokenName, 
+                /*questionToken*/ undefined, typeNode, 
+                /*initializer*/ undefined);
+                var propertyChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                propertyChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, property, { suffix: context.newLineCharacter });
+                var diag = makeStatic ? ts.Diagnostics.Declare_static_property_0 : ts.Diagnostics.Declare_property_0;
+                actions = ts.append(actions, {
+                    description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]),
+                    changes: propertyChangeTracker.getChanges()
+                });
+                if (!makeStatic) {
+                    // Index signatures cannot have the static modifier.
+                    var stringTypeNode = ts.createKeywordTypeNode(136 /* StringKeyword */);
+                    var indexingParameter = ts.createParameter(
+                    /*decorators*/ undefined, 
+                    /*modifiers*/ undefined, 
+                    /*dotDotDotToken*/ undefined, "x", 
+                    /*questionToken*/ undefined, stringTypeNode, 
+                    /*initializer*/ undefined);
+                    var indexSignature = ts.createIndexSignature(
+                    /*decorators*/ undefined, 
+                    /*modifiers*/ undefined, [indexingParameter], typeNode);
+                    var indexSignatureChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                    indexSignatureChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, indexSignature, { suffix: context.newLineCharacter });
+                    actions.push({
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Add_index_signature_for_property_0), [tokenName]),
+                        changes: indexSignatureChangeTracker.getChanges()
+                    });
+                }
+                return actions;
+            }
+            function getActionForMethodDeclaration(includeTypeScriptSyntax) {
+                if (token.parent.parent.kind === 181 /* CallExpression */) {
+                    var callExpression = token.parent.parent;
+                    var methodDeclaration = codefix.createMethodFromCallExpression(callExpression, tokenName, includeTypeScriptSyntax, makeStatic);
+                    var methodDeclarationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                    methodDeclarationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, methodDeclaration, { suffix: context.newLineCharacter });
+                    var diag = makeStatic ? ts.Diagnostics.Declare_static_method_0 : ts.Diagnostics.Declare_method_0;
+                    return {
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]),
+                        changes: methodDeclarationChangeTracker.getChanges()
+                    };
+                }
+            }
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
+                ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code],
+            getCodeActions: getActionsForCorrectSpelling
+        });
+        function getActionsForCorrectSpelling(context) {
+            var sourceFile = context.sourceFile;
+            // This is the identifier of the misspelled word. eg:
+            // this.speling = 1;
+            //      ^^^^^^^
+            var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); // TODO: GH#15852
+            var checker = context.program.getTypeChecker();
+            var suggestion;
+            if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
+                ts.Debug.assert(node.kind === 71 /* Identifier */);
+                var containingType = checker.getTypeAtLocation(node.parent.expression);
+                suggestion = checker.getSuggestionForNonexistentProperty(node, containingType);
+            }
+            else {
+                var meaning = ts.getMeaningFromLocation(node);
+                suggestion = checker.getSuggestionForNonexistentSymbol(node, ts.getTextOfNode(node), convertSemanticMeaningToSymbolFlags(meaning));
+            }
+            if (suggestion) {
+                return [{
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_spelling_to_0), [suggestion]),
+                        changes: [{
+                                fileName: sourceFile.fileName,
+                                textChanges: [{
+                                        span: { start: node.getStart(), length: node.getWidth() },
+                                        newText: suggestion
+                                    }],
+                            }],
+                    }];
+            }
+        }
+        function convertSemanticMeaningToSymbolFlags(meaning) {
+            var flags = 0;
+            if (meaning & 4 /* Namespace */) {
+                flags |= 1920 /* Namespace */;
+            }
+            if (meaning & 2 /* Type */) {
+                flags |= 793064 /* Type */;
+            }
+            if (meaning & 1 /* Value */) {
+                flags |= 107455 /* Value */;
+            }
+            return flags;
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [
+                ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
+            ],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile, start = context.span.start;
+                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+                if (!ts.isStringLiteral(token)) {
+                    throw ts.Debug.fail(); // These errors should only happen on the module name.
+                }
+                var action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
+                return action && [action];
+            },
+        });
+        function tryGetCodeActionForInstallPackageTypes(host, moduleName) {
+            var packageName = ts.getPackageName(moduleName).packageName;
+            if (!host.isKnownTypesPackageName(packageName)) {
+                // If !registry, registry not available yet, can't do anything.
+                return undefined;
+            }
+            var typesPackageName = ts.getTypesPackageName(packageName);
+            return {
+                description: "Install '" + typesPackageName + "'",
+                changes: [],
+                commands: [{ type: "install package", packageName: typesPackageName }],
+            };
+        }
+        codefix.tryGetCodeActionForInstallPackageTypes = tryGetCodeActionForInstallPackageTypes;
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code],
+            getCodeActions: getActionForClassLikeMissingAbstractMember
+        });
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code],
+            getCodeActions: getActionForClassLikeMissingAbstractMember
+        });
+        function getActionForClassLikeMissingAbstractMember(context) {
+            var sourceFile = context.sourceFile;
+            var start = context.span.start;
+            // This is the identifier in the case of a class declaration
+            // or the class keyword token in the case of a class expression.
+            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+            var checker = context.program.getTypeChecker();
+            if (ts.isClassLike(token.parent)) {
+                var classDeclaration = token.parent;
+                var extendsNode = ts.getClassExtendsHeritageClauseElement(classDeclaration);
+                var instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
+                // Note that this is ultimately derived from a map indexed by symbol names,
+                // so duplicates cannot occur.
+                var extendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType);
+                var abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember);
+                var newNodes = codefix.createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker);
+                var changes = codefix.newNodesToChanges(newNodes, ts.getOpenBraceOfClassLike(classDeclaration, sourceFile), context);
+                if (changes && changes.length > 0) {
+                    return [{
+                            description: ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_inherited_abstract_class),
+                            changes: changes
+                        }];
+                }
+            }
+            return undefined;
+        }
+        function symbolPointsToNonPrivateAndAbstractMember(symbol) {
+            var decls = symbol.getDeclarations();
+            ts.Debug.assert(!!(decls && decls.length > 0));
+            var flags = ts.getModifierFlags(decls[0]);
+            return !(flags & 8 /* Private */) && !!(flags & 128 /* Abstract */);
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+                if (token.kind !== 99 /* ThisKeyword */) {
+                    return undefined;
+                }
+                var constructor = ts.getContainingFunction(token);
+                var superCall = findSuperCall(constructor.body);
+                if (!superCall) {
+                    return undefined;
+                }
+                // figure out if the `this` access is actually inside the supercall
+                // i.e. super(this.a), since in that case we won't suggest a fix
+                if (superCall.expression && superCall.expression.kind === 181 /* CallExpression */) {
+                    var expressionArguments = superCall.expression.arguments;
+                    for (var i = 0; i < expressionArguments.length; i++) {
+                        if (expressionArguments[i].expression === token) {
+                            return undefined;
+                        }
+                    }
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(constructor, sourceFile), superCall, { suffix: context.newLineCharacter });
+                changeTracker.deleteNode(sourceFile, superCall);
+                return [{
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Make_super_call_the_first_statement_in_the_constructor),
+                        changes: changeTracker.getChanges()
+                    }];
+                function findSuperCall(n) {
+                    if (n.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(n.expression)) {
+                        return n;
+                    }
+                    if (ts.isFunctionLike(n)) {
+                        return undefined;
+                    }
+                    return ts.forEachChild(n, findSuperCall);
+                }
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+                if (token.kind !== 123 /* ConstructorKeyword */) {
+                    return undefined;
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                var superCall = ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ ts.emptyArray));
+                changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(token.parent, sourceFile), superCall, { suffix: context.newLineCharacter });
+                return [{
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_missing_super_call),
+                        changes: changeTracker.getChanges()
+                    }];
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var start = context.span.start;
+                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+                var classDeclNode = ts.getContainingClass(token);
+                if (!(token.kind === 71 /* Identifier */ && ts.isClassLike(classDeclNode))) {
+                    return undefined;
+                }
+                var heritageClauses = classDeclNode.heritageClauses;
+                if (!(heritageClauses && heritageClauses.length > 0)) {
+                    return undefined;
+                }
+                var extendsToken = heritageClauses[0].getFirstToken();
+                if (!(extendsToken && extendsToken.kind === 85 /* ExtendsKeyword */)) {
+                    return undefined;
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                changeTracker.replaceNode(sourceFile, extendsToken, ts.createToken(108 /* ImplementsKeyword */));
+                // We replace existing keywords with commas.
+                for (var i = 1; i < heritageClauses.length; i++) {
+                    var keywordToken = heritageClauses[i].getFirstToken();
+                    if (keywordToken) {
+                        changeTracker.replaceNode(sourceFile, keywordToken, ts.createToken(26 /* CommaToken */));
+                    }
+                }
+                var result = [{
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Change_extends_to_implements),
+                        changes: changeTracker.getChanges()
+                    }];
+                return result;
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+                if (token.kind !== 71 /* Identifier */) {
+                    return undefined;
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                changeTracker.replaceNode(sourceFile, token, ts.createPropertyAccess(ts.createThis(), token));
+                return [{
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_this_to_unresolved_variable),
+                        changes: changeTracker.getChanges()
+                    }];
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [
+                ts.Diagnostics._0_is_declared_but_its_value_is_never_read.code,
+                ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code
+            ],
+            getCodeActions: function (context) {
+                var sourceFile = context.sourceFile;
+                var start = context.span.start;
+                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+                // this handles var ["computed"] = 12;
+                if (token.kind === 21 /* OpenBracketToken */) {
+                    token = ts.getTokenAtPosition(sourceFile, start + 1, /*includeJsDocComment*/ false);
+                }
+                switch (token.kind) {
+                    case 71 /* Identifier */:
+                        return deleteIdentifierOrPrefixWithUnderscore(token);
+                    case 149 /* PropertyDeclaration */:
+                    case 240 /* NamespaceImport */:
+                        return [deleteNode(token.parent)];
+                    default:
+                        return deleteDefault();
+                }
+                function deleteDefault() {
+                    if (ts.isDeclarationName(token)) {
+                        return [deleteNode(token.parent)];
+                    }
+                    else if (ts.isLiteralComputedPropertyDeclarationName(token)) {
+                        return [deleteNode(token.parent.parent)];
+                    }
+                    else {
+                        return undefined;
+                    }
+                }
+                function prefixIdentifierWithUnderscore(identifier) {
+                    var startPosition = identifier.getStart(sourceFile, /*includeJsDocComment*/ false);
+                    return {
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Prefix_0_with_an_underscore), { 0: token.getText() }),
+                        changes: [{
+                                fileName: sourceFile.path,
+                                textChanges: [{
+                                        span: { start: startPosition, length: 0 },
+                                        newText: "_"
+                                    }]
+                            }]
+                    };
+                }
+                function deleteIdentifierOrPrefixWithUnderscore(identifier) {
+                    var parent = identifier.parent;
+                    switch (parent.kind) {
+                        case 226 /* VariableDeclaration */:
+                            return deleteVariableDeclarationOrPrefixWithUnderscore(identifier, parent);
+                        case 145 /* TypeParameter */:
+                            var typeParameters = parent.parent.typeParameters;
+                            if (typeParameters.length === 1) {
+                                var previousToken = ts.getTokenAtPosition(sourceFile, typeParameters.pos - 1, /*includeJsDocComment*/ false);
+                                var nextToken = ts.getTokenAtPosition(sourceFile, typeParameters.end, /*includeJsDocComment*/ false);
+                                ts.Debug.assert(previousToken.kind === 27 /* LessThanToken */);
+                                ts.Debug.assert(nextToken.kind === 29 /* GreaterThanToken */);
+                                return [deleteNodeRange(previousToken, nextToken)];
+                            }
+                            else {
+                                return [deleteNodeInList(parent)];
+                            }
+                        case 146 /* Parameter */:
+                            var functionDeclaration = parent.parent;
+                            return [functionDeclaration.parameters.length === 1 ? deleteNode(parent) : deleteNodeInList(parent),
+                                prefixIdentifierWithUnderscore(identifier)];
+                        // handle case where 'import a = A;'
+                        case 237 /* ImportEqualsDeclaration */:
+                            var importEquals = ts.getAncestor(identifier, 237 /* ImportEqualsDeclaration */);
+                            return [deleteNode(importEquals)];
+                        case 242 /* ImportSpecifier */:
+                            var namedImports = parent.parent;
+                            if (namedImports.elements.length === 1) {
+                                return deleteNamedImportBinding(namedImports);
+                            }
+                            else {
+                                // delete import specifier
+                                return [deleteNodeInList(parent)];
+                            }
+                        case 239 /* ImportClause */:// this covers both 'import |d|' and 'import |d,| *'
+                            var importClause = parent;
+                            if (!importClause.namedBindings) {
+                                var importDecl = ts.getAncestor(importClause, 238 /* ImportDeclaration */);
+                                return [deleteNode(importDecl)];
+                            }
+                            else {
+                                // import |d,| * as ns from './file'
+                                var start_6 = importClause.name.getStart(sourceFile);
+                                var nextToken = ts.getTokenAtPosition(sourceFile, importClause.name.end, /*includeJsDocComment*/ false);
+                                if (nextToken && nextToken.kind === 26 /* CommaToken */) {
+                                    // shift first non-whitespace position after comma to the start position of the node
+                                    return [deleteRange({ pos: start_6, end: ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) })];
+                                }
+                                else {
+                                    return [deleteNode(importClause.name)];
+                                }
+                            }
+                        case 240 /* NamespaceImport */:
+                            return deleteNamedImportBinding(parent);
+                        default:
+                            return deleteDefault();
+                    }
+                }
+                function deleteNamedImportBinding(namedBindings) {
+                    if (namedBindings.parent.name) {
+                        // Delete named imports while preserving the default import
+                        // import d|, * as ns| from './file'
+                        // import d|, { a }| from './file'
+                        var previousToken = ts.getTokenAtPosition(sourceFile, namedBindings.pos - 1, /*includeJsDocComment*/ false);
+                        if (previousToken && previousToken.kind === 26 /* CommaToken */) {
+                            return [deleteRange({ pos: previousToken.getStart(), end: namedBindings.end })];
+                        }
+                        return undefined;
+                    }
+                    else {
+                        // Delete the entire import declaration
+                        // |import * as ns from './file'|
+                        // |import { a } from './file'|
+                        var importDecl = ts.getAncestor(namedBindings, 238 /* ImportDeclaration */);
+                        return [deleteNode(importDecl)];
+                    }
+                }
+                // token.parent is a variableDeclaration
+                function deleteVariableDeclarationOrPrefixWithUnderscore(identifier, varDecl) {
+                    switch (varDecl.parent.parent.kind) {
+                        case 214 /* ForStatement */:
+                            var forStatement = varDecl.parent.parent;
+                            var forInitializer = forStatement.initializer;
+                            return [forInitializer.declarations.length === 1 ? deleteNode(forInitializer) : deleteNodeInList(varDecl)];
+                        case 216 /* ForOfStatement */:
+                            var forOfStatement = varDecl.parent.parent;
+                            ts.Debug.assert(forOfStatement.initializer.kind === 227 /* VariableDeclarationList */);
+                            var forOfInitializer = forOfStatement.initializer;
+                            return [
+                                replaceNode(forOfInitializer.declarations[0], ts.createObjectLiteral()),
+                                prefixIdentifierWithUnderscore(identifier)
+                            ];
+                        case 215 /* ForInStatement */:
+                            // There is no valid fix in the case of:
+                            //  for .. in
+                            return [prefixIdentifierWithUnderscore(identifier)];
+                        default:
+                            var variableStatement = varDecl.parent.parent;
+                            if (variableStatement.declarationList.declarations.length === 1) {
+                                return [deleteNode(variableStatement)];
+                            }
+                            else {
+                                return [deleteNodeInList(varDecl)];
+                            }
+                    }
+                }
+                function deleteNode(n) {
+                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNode(sourceFile, n));
+                }
+                function deleteRange(range) {
+                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteRange(sourceFile, range));
+                }
+                function deleteNodeInList(n) {
+                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeInList(sourceFile, n));
+                }
+                function deleteNodeRange(start, end) {
+                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeRange(sourceFile, start, end));
+                }
+                function replaceNode(n, newNode) {
+                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).replaceNode(sourceFile, n, newNode));
+                }
+                function makeChange(changeTracker) {
+                    return {
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),
+                        changes: changeTracker.getChanges()
+                    };
+                }
+            }
+        });
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code],
+            getCodeActions: getActionsForJSDocTypes
+        });
+        function getActionsForJSDocTypes(context) {
+            var sourceFile = context.sourceFile;
+            var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+            // NOTE: Some locations are not handled yet:
+            // MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments
+            var decl = ts.findAncestor(node, function (n) {
+                return n.kind === 202 /* AsExpression */ ||
+                    n.kind === 155 /* CallSignature */ ||
+                    n.kind === 156 /* ConstructSignature */ ||
+                    n.kind === 228 /* FunctionDeclaration */ ||
+                    n.kind === 153 /* GetAccessor */ ||
+                    n.kind === 157 /* IndexSignature */ ||
+                    n.kind === 172 /* MappedType */ ||
+                    n.kind === 151 /* MethodDeclaration */ ||
+                    n.kind === 150 /* MethodSignature */ ||
+                    n.kind === 146 /* Parameter */ ||
+                    n.kind === 149 /* PropertyDeclaration */ ||
+                    n.kind === 148 /* PropertySignature */ ||
+                    n.kind === 154 /* SetAccessor */ ||
+                    n.kind === 231 /* TypeAliasDeclaration */ ||
+                    n.kind === 184 /* TypeAssertionExpression */ ||
+                    n.kind === 226 /* VariableDeclaration */;
+            });
+            if (!decl)
+                return;
+            var checker = context.program.getTypeChecker();
+            var jsdocType = decl.type;
+            if (!jsdocType)
+                return;
+            var original = ts.getTextOfNode(jsdocType);
+            var type = checker.getTypeFromTypeNode(jsdocType);
+            var actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */))];
+            if (jsdocType.kind === 270 /* JSDocNullableType */) {
+                // for nullable types, suggest the flow-compatible `T | null | undefined`
+                // in addition to the jsdoc/closure-compatible `T | null`
+                var replacementWithUndefined = checker.typeToString(checker.getNullableType(type, 2048 /* Undefined */), /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */);
+                actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined));
+            }
+            return actions;
+        }
+        function createAction(declaration, fileName, original, replacement) {
+            return {
+                description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_0_to_1), [original, replacement]),
+                changes: [{
+                        fileName: fileName,
+                        textChanges: [{
+                                span: { start: declaration.getStart(), length: declaration.getWidth() },
+                                newText: replacement
+                            }]
+                    }],
+            };
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        var ChangeTracker = ts.textChanges.ChangeTracker;
+        codefix.registerCodeFix({
+            errorCodes: [
+                ts.Diagnostics.Cannot_find_name_0.code,
+                ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
+                ts.Diagnostics.Cannot_find_namespace_0.code,
+                ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
+            ],
+            getCodeActions: getImportCodeActions
+        });
+        var ModuleSpecifierComparison;
+        (function (ModuleSpecifierComparison) {
+            ModuleSpecifierComparison[ModuleSpecifierComparison["Better"] = 0] = "Better";
+            ModuleSpecifierComparison[ModuleSpecifierComparison["Equal"] = 1] = "Equal";
+            ModuleSpecifierComparison[ModuleSpecifierComparison["Worse"] = 2] = "Worse";
+        })(ModuleSpecifierComparison || (ModuleSpecifierComparison = {}));
+        var ImportCodeActionMap = /** @class */ (function () {
+            function ImportCodeActionMap() {
+                this.symbolIdToActionMap = [];
+            }
+            ImportCodeActionMap.prototype.addAction = function (symbolId, newAction) {
+                var actions = this.symbolIdToActionMap[symbolId];
+                if (!actions) {
+                    this.symbolIdToActionMap[symbolId] = [newAction];
+                    return;
+                }
+                if (newAction.kind === "CodeChange") {
+                    actions.push(newAction);
+                    return;
+                }
+                var updatedNewImports = [];
+                for (var _i = 0, _a = this.symbolIdToActionMap[symbolId]; _i < _a.length; _i++) {
+                    var existingAction = _a[_i];
+                    if (existingAction.kind === "CodeChange") {
+                        // only import actions should compare
+                        updatedNewImports.push(existingAction);
+                        continue;
+                    }
+                    switch (this.compareModuleSpecifiers(existingAction.moduleSpecifier, newAction.moduleSpecifier)) {
+                        case 0 /* Better */:
+                            // the new one is not worth considering if it is a new import.
+                            // However if it is instead a insertion into existing import, the user might want to use
+                            // the module specifier even it is worse by our standards. So keep it.
+                            if (newAction.kind === "NewImport") {
+                                return;
+                            }
+                        // falls through
+                        case 1 /* Equal */:
+                            // the current one is safe. But it is still possible that the new one is worse
+                            // than another existing one. For example, you may have new imports from "./foo/bar"
+                            // and "bar", when the new one is "bar/bar2" and the current one is "./foo/bar". The new
+                            // one and the current one are not comparable (one relative path and one absolute path),
+                            // but the new one is worse than the other one, so should not add to the list.
+                            updatedNewImports.push(existingAction);
+                            break;
+                        case 2 /* Worse */:
+                            // the existing one is worse, remove from the list.
+                            continue;
+                    }
+                }
+                // if we reach here, it means the new one is better or equal to all of the existing ones.
+                updatedNewImports.push(newAction);
+                this.symbolIdToActionMap[symbolId] = updatedNewImports;
+            };
+            ImportCodeActionMap.prototype.addActions = function (symbolId, newActions) {
+                for (var _i = 0, newActions_1 = newActions; _i < newActions_1.length; _i++) {
+                    var newAction = newActions_1[_i];
+                    this.addAction(symbolId, newAction);
+                }
+            };
+            ImportCodeActionMap.prototype.getAllActions = function () {
+                var result = [];
+                for (var key in this.symbolIdToActionMap) {
+                    result = ts.concatenate(result, this.symbolIdToActionMap[key]);
+                }
+                return result;
+            };
+            ImportCodeActionMap.prototype.compareModuleSpecifiers = function (moduleSpecifier1, moduleSpecifier2) {
+                if (moduleSpecifier1 === moduleSpecifier2) {
+                    return 1 /* Equal */;
+                }
+                // if moduleSpecifier1 (ms1) is a substring of ms2, then it is better
+                if (moduleSpecifier2.indexOf(moduleSpecifier1) === 0) {
+                    return 0 /* Better */;
+                }
+                if (moduleSpecifier1.indexOf(moduleSpecifier2) === 0) {
+                    return 2 /* Worse */;
+                }
+                // if both are relative paths, and ms1 has fewer levels, then it is better
+                if (ts.isExternalModuleNameRelative(moduleSpecifier1) && ts.isExternalModuleNameRelative(moduleSpecifier2)) {
+                    var regex = new RegExp(ts.directorySeparator, "g");
+                    var moduleSpecifier1LevelCount = (moduleSpecifier1.match(regex) || []).length;
+                    var moduleSpecifier2LevelCount = (moduleSpecifier2.match(regex) || []).length;
+                    return moduleSpecifier1LevelCount < moduleSpecifier2LevelCount
+                        ? 0 /* Better */
+                        : moduleSpecifier1LevelCount === moduleSpecifier2LevelCount
+                            ? 1 /* Equal */
+                            : 2 /* Worse */;
+                }
+                // the equal cases include when the two specifiers are not comparable.
+                return 1 /* Equal */;
+            };
+            return ImportCodeActionMap;
+        }());
+        function createCodeAction(description, diagnosticArgs, changes, kind, moduleSpecifier) {
+            return {
+                description: ts.formatMessage.apply(undefined, [undefined, description].concat(diagnosticArgs)),
+                changes: changes,
+                kind: kind,
+                moduleSpecifier: moduleSpecifier
+            };
+        }
+        function convertToImportCodeFixContext(context) {
+            var useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false;
+            var checker = context.program.getTypeChecker();
+            var symbolToken = ts.getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false);
+            return {
+                host: context.host,
+                newLineCharacter: context.newLineCharacter,
+                rulesProvider: context.rulesProvider,
+                sourceFile: context.sourceFile,
+                checker: checker,
+                compilerOptions: context.program.getCompilerOptions(),
+                cachedImportDeclarations: [],
+                getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames),
+                symbolName: symbolToken.getText(),
+                symbolToken: symbolToken,
+            };
+        }
+        var ImportKind;
+        (function (ImportKind) {
+            ImportKind[ImportKind["Named"] = 0] = "Named";
+            ImportKind[ImportKind["Default"] = 1] = "Default";
+            ImportKind[ImportKind["Namespace"] = 2] = "Namespace";
+        })(ImportKind = codefix.ImportKind || (codefix.ImportKind = {}));
+        function getCodeActionForImport(moduleSymbol, context) {
+            var declarations = getImportDeclarations(moduleSymbol, context.checker, context.sourceFile, context.cachedImportDeclarations);
+            var actions = [];
+            if (context.symbolToken) {
+                // It is possible that multiple import statements with the same specifier exist in the file.
+                // e.g.
+                //
+                //     import * as ns from "foo";
+                //     import { member1, member2 } from "foo";
+                //
+                //     member3/**/ <-- cusor here
+                //
+                // in this case we should provie 2 actions:
+                //     1. change "member3" to "ns.member3"
+                //     2. add "member3" to the second import statement's import list
+                // and it is up to the user to decide which one fits best.
+                for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) {
+                    var declaration = declarations_13[_i];
+                    var namespace = getNamespaceImportName(declaration);
+                    if (namespace) {
+                        actions.push(getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken));
+                    }
+                }
+            }
+            actions.push(getCodeActionForAddImport(moduleSymbol, context, declarations));
+            return actions;
+        }
+        codefix.getCodeActionForImport = getCodeActionForImport;
+        function getNamespaceImportName(declaration) {
+            if (declaration.kind === 238 /* ImportDeclaration */) {
+                var namedBindings = declaration.importClause && declaration.importClause.namedBindings;
+                return namedBindings && namedBindings.kind === 240 /* NamespaceImport */ ? namedBindings.name : undefined;
+            }
+            else {
+                return declaration.name;
+            }
+        }
+        // TODO(anhans): This doesn't seem important to cache... just use an iterator instead of creating a new array?
+        function getImportDeclarations(moduleSymbol, checker, _a, cachedImportDeclarations) {
+            var imports = _a.imports;
+            if (cachedImportDeclarations === void 0) { cachedImportDeclarations = []; }
+            var moduleSymbolId = ts.getUniqueSymbolId(moduleSymbol, checker);
+            var cached = cachedImportDeclarations[moduleSymbolId];
+            if (!cached) {
+                cached = cachedImportDeclarations[moduleSymbolId] = ts.mapDefined(imports, function (importModuleSpecifier) {
+                    return checker.getSymbolAtLocation(importModuleSpecifier) === moduleSymbol ? getImportDeclaration(importModuleSpecifier) : undefined;
+                });
+            }
+            return cached;
+        }
+        function getImportDeclaration(_a) {
+            var parent = _a.parent;
+            switch (parent.kind) {
+                case 238 /* ImportDeclaration */:
+                    return parent;
+                case 248 /* ExternalModuleReference */:
+                    return parent.parent;
+                default:
+                    ts.Debug.assert(parent.kind === 244 /* ExportDeclaration */);
+                    // Ignore these, can't add imports to them.
+                    return undefined;
+            }
+        }
+        function getCodeActionForNewImport(context, moduleSpecifier) {
+            var kind = context.kind, sourceFile = context.sourceFile, newLineCharacter = context.newLineCharacter, symbolName = context.symbolName;
+            var lastImportDeclaration = ts.findLast(sourceFile.statements, ts.isAnyImportSyntax);
+            var moduleSpecifierWithoutQuotes = ts.stripQuotes(moduleSpecifier);
+            var importDecl = ts.createImportDeclaration(
+            /*decorators*/ undefined, 
+            /*modifiers*/ undefined, createImportClauseOfKind(kind, symbolName), createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes));
+            var changes = ChangeTracker.with(context, function (changeTracker) {
+                if (lastImportDeclaration) {
+                    changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: newLineCharacter });
+                }
+                else {
+                    changeTracker.insertNodeAt(sourceFile, ts.getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + newLineCharacter + newLineCharacter });
+                }
+            });
+            // if this file doesn't have any import statements, insert an import statement and then insert a new line
+            // between the only import statement and user code. Otherwise just insert the statement because chances
+            // are there are already a new line seperating code and import statements.
+            return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, moduleSpecifierWithoutQuotes], changes, "NewImport", moduleSpecifierWithoutQuotes);
+        }
+        function createStringLiteralWithQuoteStyle(sourceFile, text) {
+            var literal = ts.createLiteral(text);
+            var firstModuleSpecifier = ts.firstOrUndefined(sourceFile.imports);
+            literal.singleQuote = !!firstModuleSpecifier && !ts.isStringDoubleQuoted(firstModuleSpecifier, sourceFile);
+            return literal;
+        }
+        function createImportClauseOfKind(kind, symbolName) {
+            var id = ts.createIdentifier(symbolName);
+            switch (kind) {
+                case 1 /* Default */:
+                    return ts.createImportClause(id, /*namedBindings*/ undefined);
+                case 2 /* Namespace */:
+                    return ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(id));
+                case 0 /* Named */:
+                    return ts.createImportClause(/*name*/ undefined, ts.createNamedImports([ts.createImportSpecifier(/*propertyName*/ undefined, id)]));
+                default:
+                    ts.Debug.assertNever(kind);
+            }
+        }
+        function getModuleSpecifierForNewImport(sourceFile, moduleSymbol, options, getCanonicalFileName, host) {
+            var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
+            var sourceDirectory = ts.getDirectoryPath(sourceFile.fileName);
+            return tryGetModuleNameFromAmbientModule(moduleSymbol) ||
+                tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) ||
+                tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) ||
+                tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) ||
+                options.rootDirs && tryGetModuleNameFromRootDirs(options.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
+                ts.removeFileExtension(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName));
+        }
+        function tryGetModuleNameFromAmbientModule(moduleSymbol) {
+            var decl = moduleSymbol.valueDeclaration;
+            if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) {
+                return decl.name.text;
+            }
+        }
+        function tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) {
+            if (!options.baseUrl) {
+                return undefined;
+            }
+            var relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl, getCanonicalFileName);
+            if (!relativeName) {
+                return undefined;
+            }
+            var relativeNameWithIndex = ts.removeFileExtension(relativeName);
+            relativeName = removeExtensionAndIndexPostFix(relativeName);
+            if (options.paths) {
+                for (var key in options.paths) {
+                    for (var _i = 0, _a = options.paths[key]; _i < _a.length; _i++) {
+                        var pattern = _a[_i];
+                        var indexOfStar = pattern.indexOf("*");
+                        if (indexOfStar === 0 && pattern.length === 1) {
+                            continue;
+                        }
+                        else if (indexOfStar !== -1) {
+                            var prefix = pattern.substr(0, indexOfStar);
+                            var suffix = pattern.substr(indexOfStar + 1);
+                            if (relativeName.length >= prefix.length + suffix.length &&
+                                ts.startsWith(relativeName, prefix) &&
+                                ts.endsWith(relativeName, suffix)) {
+                                var matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length);
+                                return key.replace("\*", matchedStar);
+                            }
+                        }
+                        else if (pattern === relativeName || pattern === relativeNameWithIndex) {
+                            return key;
+                        }
+                    }
+                }
+            }
+            return relativeName;
+        }
+        function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) {
+            var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
+            if (normalizedTargetPath === undefined) {
+                return undefined;
+            }
+            var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName);
+            var relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath, getCanonicalFileName) : normalizedTargetPath;
+            return ts.removeFileExtension(relativePath);
+        }
+        function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) {
+            var roots = ts.getEffectiveTypeRoots(options, host);
+            return roots && ts.firstDefined(roots, function (unNormalizedTypeRoot) {
+                var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
+                if (ts.startsWith(moduleFileName, typeRoot)) {
+                    return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1));
+                }
+            });
+        }
+        function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) {
+            if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) {
+                // nothing to do here
+                return undefined;
+            }
+            var parts = getNodeModulePathParts(moduleFileName);
+            if (!parts) {
+                return undefined;
+            }
+            // Simplify the full file path to something that can be resolved by Node.
+            // If the module could be imported by a directory name, use that directory's name
+            var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
+            // Get a path that's relative to node_modules or the importing file's path
+            moduleSpecifier = getNodeResolvablePath(moduleSpecifier);
+            // If the module was found in @types, get the actual Node package name
+            return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier);
+            function getDirectoryOrExtensionlessFileName(path) {
+                // If the file is the main module, it can be imported by the package name
+                var packageRootPath = path.substring(0, parts.packageRootIndex);
+                var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
+                if (host.fileExists(packageJsonPath)) {
+                    var packageJsonContent = JSON.parse(host.readFile(packageJsonPath));
+                    if (packageJsonContent) {
+                        var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
+                        if (mainFileRelative) {
+                            var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
+                            if (mainExportFile === getCanonicalFileName(path)) {
+                                return packageRootPath;
+                            }
+                        }
+                    }
+                }
+                // We still have a file name - remove the extension
+                var fullModulePathWithoutExtension = ts.removeFileExtension(path);
+                // If the file is /index, it can be imported by its directory name
+                if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") {
+                    return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
+                }
+                return fullModulePathWithoutExtension;
+            }
+            function getNodeResolvablePath(path) {
+                var basePath = path.substring(0, parts.topLevelNodeModulesIndex);
+                if (sourceDirectory.indexOf(basePath) === 0) {
+                    // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+                    return path.substring(parts.topLevelPackageNameIndex + 1);
+                }
+                else {
+                    return getRelativePath(path, sourceDirectory, getCanonicalFileName);
+                }
+            }
+        }
+        function getNodeModulePathParts(fullPath) {
+            // If fullPath can't be valid module file within node_modules, returns undefined.
+            // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
+            // Returns indices:                       ^            ^                                                      ^             ^
+            var topLevelNodeModulesIndex = 0;
+            var topLevelPackageNameIndex = 0;
+            var packageRootIndex = 0;
+            var fileNameIndex = 0;
+            var States;
+            (function (States) {
+                States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules";
+                States[States["NodeModules"] = 1] = "NodeModules";
+                States[States["Scope"] = 2] = "Scope";
+                States[States["PackageContent"] = 3] = "PackageContent";
+            })(States || (States = {}));
+            var partStart = 0;
+            var partEnd = 0;
+            var state = 0 /* BeforeNodeModules */;
+            while (partEnd >= 0) {
+                partStart = partEnd;
+                partEnd = fullPath.indexOf("/", partStart + 1);
+                switch (state) {
+                    case 0 /* BeforeNodeModules */:
+                        if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
+                            topLevelNodeModulesIndex = partStart;
+                            topLevelPackageNameIndex = partEnd;
+                            state = 1 /* NodeModules */;
+                        }
+                        break;
+                    case 1 /* NodeModules */:
+                    case 2 /* Scope */:
+                        if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") {
+                            state = 2 /* Scope */;
+                        }
+                        else {
+                            packageRootIndex = partEnd;
+                            state = 3 /* PackageContent */;
+                        }
+                        break;
+                    case 3 /* PackageContent */:
+                        if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
+                            state = 1 /* NodeModules */;
+                        }
+                        else {
+                            state = 3 /* PackageContent */;
+                        }
+                        break;
+                }
+            }
+            fileNameIndex = partStart;
+            return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined;
+        }
+        function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) {
+            return ts.firstDefined(rootDirs, function (rootDir) { return getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); });
+        }
+        function removeExtensionAndIndexPostFix(fileName) {
+            fileName = ts.removeFileExtension(fileName);
+            if (ts.endsWith(fileName, "/index")) {
+                fileName = fileName.substr(0, fileName.length - 6 /* "/index".length */);
+            }
+            return fileName;
+        }
+        function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) {
+            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
+            return ts.isRootedDiskPath(relativePath) || ts.startsWith(relativePath, "..") ? undefined : relativePath;
+        }
+        function getRelativePath(path, directoryPath, getCanonicalFileName) {
+            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
+            return !ts.pathIsRelative(relativePath) ? "./" + relativePath : relativePath;
+        }
+        function getCodeActionForAddImport(moduleSymbol, ctx, declarations) {
+            var fromExistingImport = ts.firstDefined(declarations, function (declaration) {
+                if (declaration.kind === 238 /* ImportDeclaration */ && declaration.importClause) {
+                    var changes = tryUpdateExistingImport(ctx, declaration.importClause);
+                    if (changes) {
+                        var moduleSpecifierWithoutQuotes = ts.stripQuotes(declaration.moduleSpecifier.getText());
+                        return createCodeAction(ts.Diagnostics.Add_0_to_existing_import_declaration_from_1, [ctx.symbolName, moduleSpecifierWithoutQuotes], changes, "InsertingIntoExistingImport", moduleSpecifierWithoutQuotes);
+                    }
+                }
+            });
+            if (fromExistingImport) {
+                return fromExistingImport;
+            }
+            var moduleSpecifier = ts.firstDefined(declarations, moduleSpecifierFromAnyImport)
+                || getModuleSpecifierForNewImport(ctx.sourceFile, moduleSymbol, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
+            return getCodeActionForNewImport(ctx, moduleSpecifier);
+        }
+        function moduleSpecifierFromAnyImport(node) {
+            var expression = node.kind === 238 /* ImportDeclaration */
+                ? node.moduleSpecifier
+                : node.moduleReference.kind === 248 /* ExternalModuleReference */
+                    ? node.moduleReference.expression
+                    : undefined;
+            return expression && ts.isStringLiteral(expression) ? expression.text : undefined;
+        }
+        function tryUpdateExistingImport(context, importClause) {
+            var symbolName = context.symbolName, sourceFile = context.sourceFile, kind = context.kind;
+            var name = importClause.name, namedBindings = importClause.namedBindings;
+            switch (kind) {
+                case 1 /* Default */:
+                    return name ? undefined : ChangeTracker.with(context, function (t) {
+                        return t.replaceNode(sourceFile, importClause, ts.createImportClause(ts.createIdentifier(symbolName), namedBindings));
+                    });
+                case 0 /* Named */: {
+                    var newImportSpecifier_1 = ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(symbolName));
+                    if (namedBindings && namedBindings.kind === 241 /* NamedImports */ && namedBindings.elements.length !== 0) {
+                        // There are already named imports; add another.
+                        return ChangeTracker.with(context, function (t) { return t.insertNodeInListAfter(sourceFile, namedBindings.elements[namedBindings.elements.length - 1], newImportSpecifier_1); });
+                    }
+                    if (!namedBindings || namedBindings.kind === 241 /* NamedImports */ && namedBindings.elements.length === 0) {
+                        return ChangeTracker.with(context, function (t) {
+                            return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamedImports([newImportSpecifier_1])));
+                        });
+                    }
+                    return undefined;
+                }
+                case 2 /* Namespace */:
+                    return namedBindings ? undefined : ChangeTracker.with(context, function (t) {
+                        return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamespaceImport(ts.createIdentifier(symbolName))));
+                    });
+                default:
+                    ts.Debug.assertNever(kind);
+            }
+        }
+        function getCodeActionForUseExistingNamespaceImport(namespacePrefix, context, symbolToken) {
+            var symbolName = context.symbolName, sourceFile = context.sourceFile;
+            /**
+             * Cases:
+             *     import * as ns from "mod"
+             *     import default, * as ns from "mod"
+             *     import ns = require("mod")
+             *
+             * Because there is no import list, we alter the reference to include the
+             * namespace instead of altering the import declaration. For example, "foo" would
+             * become "ns.foo"
+             */
+            return createCodeAction(ts.Diagnostics.Change_0_to_1, [symbolName, namespacePrefix + "." + symbolName], ChangeTracker.with(context, function (tracker) {
+                return tracker.replaceNode(sourceFile, symbolToken, ts.createPropertyAccess(ts.createIdentifier(namespacePrefix), symbolName));
+            }), "CodeChange", 
+            /*moduleSpecifier*/ undefined);
+        }
+        function getImportCodeActions(context) {
+            var importFixContext = convertToImportCodeFixContext(context);
+            return context.errorCode === ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
+                ? getActionsForUMDImport(importFixContext)
+                : getActionsForNonUMDImport(importFixContext, context.program.getSourceFiles(), context.cancellationToken);
+        }
+        function getActionsForUMDImport(context) {
+            var checker = context.checker, symbolToken = context.symbolToken;
+            var umdSymbol = checker.getSymbolAtLocation(symbolToken);
+            var symbol;
+            var symbolName;
+            if (umdSymbol.flags & 2097152 /* Alias */) {
+                symbol = checker.getAliasedSymbol(umdSymbol);
+                symbolName = context.symbolName;
+            }
+            else if (ts.isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) {
+                // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
+                symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, 107455 /* Value */));
+                symbolName = symbol.name;
+            }
+            else {
+                ts.Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
+            }
+            return getCodeActionForImport(symbol, __assign({}, context, { symbolName: symbolName, kind: 2 /* Namespace */ }));
+        }
+        function getActionsForNonUMDImport(context, allSourceFiles, cancellationToken) {
+            var sourceFile = context.sourceFile, checker = context.checker, symbolName = context.symbolName, symbolToken = context.symbolToken;
+            // "default" is a keyword and not a legal identifier for the import, so we don't expect it here
+            ts.Debug.assert(symbolName !== "default");
+            var symbolIdActionMap = new ImportCodeActionMap();
+            var currentTokenMeaning = ts.getMeaningFromLocation(symbolToken);
+            forEachExternalModule(checker, allSourceFiles, function (moduleSymbol) {
+                if (moduleSymbol === sourceFile.symbol) {
+                    return;
+                }
+                cancellationToken.throwIfCancellationRequested();
+                // check the default export
+                var defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
+                if (defaultExport) {
+                    var localSymbol = ts.getLocalSymbolForExportDefault(defaultExport);
+                    if (localSymbol && localSymbol.escapedName === symbolName && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
+                        // check if this symbol is already used
+                        var symbolId = ts.getUniqueSymbolId(localSymbol, checker);
+                        symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 1 /* Default */ })));
+                    }
+                }
+                // check exports with the same name
+                var exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol);
+                if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
+                    var symbolId = ts.getUniqueSymbolId(exportSymbolWithIdenticalName, checker);
+                    symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 0 /* Named */ })));
+                }
+            });
+            return symbolIdActionMap.getAllActions();
+        }
+        function checkSymbolHasMeaning(_a, meaning) {
+            var declarations = _a.declarations;
+            return ts.some(declarations, function (decl) { return !!(ts.getMeaningFromDeclaration(decl) & meaning); });
+        }
+        function forEachExternalModule(checker, allSourceFiles, cb) {
+            for (var _i = 0, _a = checker.getAmbientModules(); _i < _a.length; _i++) {
+                var ambient = _a[_i];
+                cb(ambient);
+            }
+            for (var _b = 0, allSourceFiles_1 = allSourceFiles; _b < allSourceFiles_1.length; _b++) {
+                var sourceFile = allSourceFiles_1[_b];
+                if (ts.isExternalOrCommonJsModule(sourceFile)) {
+                    cb(sourceFile.symbol);
+                }
+            }
+        }
+        codefix.forEachExternalModule = forEachExternalModule;
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: getApplicableDiagnosticCodes(),
+            getCodeActions: getDisableJsDiagnosticsCodeActions
+        });
+        function getApplicableDiagnosticCodes() {
+            var allDiagnostcs = ts.Diagnostics;
+            return Object.keys(allDiagnostcs)
+                .filter(function (d) { return allDiagnostcs[d] && allDiagnostcs[d].category === ts.DiagnosticCategory.Error; })
+                .map(function (d) { return allDiagnostcs[d].code; });
+        }
+        function getIgnoreCommentLocationForLocation(sourceFile, position, newLineCharacter) {
+            var line = ts.getLineAndCharacterOfPosition(sourceFile, position).line;
+            var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
+            var startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
+            // First try to see if we can put the '// @ts-ignore' on the previous line.
+            // We need to make sure that we are not in the middle of a string literal or a comment.
+            // We also want to check if the previous line holds a comment for a node on the next line
+            // if so, we do not want to separate the node from its comment if we can.
+            if (!ts.isInComment(sourceFile, startPosition) && !ts.isInString(sourceFile, startPosition) && !ts.isInTemplateString(sourceFile, startPosition)) {
+                var token = ts.getTouchingToken(sourceFile, startPosition, /*includeJsDocComment*/ false);
+                var tokenLeadingCommnets = ts.getLeadingCommentRangesOfNode(token, sourceFile);
+                if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
+                    return {
+                        span: { start: startPosition, length: 0 },
+                        newText: "// @ts-ignore" + newLineCharacter
+                    };
+                }
+            }
+            // If all fails, add an extra new line immediately before the error span.
+            return {
+                span: { start: position, length: 0 },
+                newText: (position === startPosition ? "" : newLineCharacter) + "// @ts-ignore" + newLineCharacter
+            };
+        }
+        function getDisableJsDiagnosticsCodeActions(context) {
+            var sourceFile = context.sourceFile, program = context.program, newLineCharacter = context.newLineCharacter, span = context.span;
+            if (!ts.isInJavaScriptFile(sourceFile) || !ts.isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
+                return undefined;
+            }
+            return [{
+                    description: ts.getLocaleSpecificMessage(ts.Diagnostics.Ignore_this_error_message),
+                    changes: [{
+                            fileName: sourceFile.fileName,
+                            textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)]
+                        }]
+                },
+                {
+                    description: ts.getLocaleSpecificMessage(ts.Diagnostics.Disable_checking_for_this_file),
+                    changes: [{
+                            fileName: sourceFile.fileName,
+                            textChanges: [{
+                                    span: {
+                                        start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
+                                        length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
+                                    },
+                                    newText: "// @ts-nocheck" + newLineCharacter
+                                }]
+                        }]
+                }];
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        function newNodesToChanges(newNodes, insertAfter, context) {
+            var sourceFile = context.sourceFile;
+            var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+            for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) {
+                var newNode = newNodes_1[_i];
+                changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter });
+            }
+            var changes = changeTracker.getChanges();
+            if (!ts.some(changes)) {
+                return changes;
+            }
+            ts.Debug.assert(changes.length === 1);
+            var consolidatedChanges = [{
+                    fileName: changes[0].fileName,
+                    textChanges: [{
+                            span: changes[0].textChanges[0].span,
+                            newText: changes[0].textChanges.reduce(function (prev, cur) { return prev + cur.newText; }, "")
+                        }]
+                }];
+            return consolidatedChanges;
+        }
+        codefix.newNodesToChanges = newNodesToChanges;
+        /**
+         * Finds members of the resolved type that are missing in the class pointed to by class decl
+         * and generates source code for the missing members.
+         * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
+         * @returns Empty string iff there are no member insertions.
+         */
+        function createMissingMemberNodes(classDeclaration, possiblyMissingSymbols, checker) {
+            var classMembers = classDeclaration.symbol.members;
+            var missingMembers = possiblyMissingSymbols.filter(function (symbol) { return !classMembers.has(symbol.escapedName); });
+            var newNodes = [];
+            for (var _i = 0, missingMembers_1 = missingMembers; _i < missingMembers_1.length; _i++) {
+                var symbol = missingMembers_1[_i];
+                var newNode = createNewNodeForMemberSymbol(symbol, classDeclaration, checker);
+                if (newNode) {
+                    if (Array.isArray(newNode)) {
+                        newNodes = newNodes.concat(newNode);
+                    }
+                    else {
+                        newNodes.push(newNode);
+                    }
+                }
+            }
+            return newNodes;
+        }
+        codefix.createMissingMemberNodes = createMissingMemberNodes;
+        /**
+         * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
+         */
+        function createNewNodeForMemberSymbol(symbol, enclosingDeclaration, checker) {
+            var declarations = symbol.getDeclarations();
+            if (!(declarations && declarations.length)) {
+                return undefined;
+            }
+            var declaration = declarations[0];
+            // Clone name to remove leading trivia.
+            var name = ts.getSynthesizedClone(ts.getNameOfDeclaration(declaration));
+            var visibilityModifier = createVisibilityModifier(ts.getModifierFlags(declaration));
+            var modifiers = visibilityModifier ? ts.createNodeArray([visibilityModifier]) : undefined;
+            var type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
+            var optional = !!(symbol.flags & 16777216 /* Optional */);
+            switch (declaration.kind) {
+                case 153 /* GetAccessor */:
+                case 154 /* SetAccessor */:
+                case 148 /* PropertySignature */:
+                case 149 /* PropertyDeclaration */:
+                    var typeNode = checker.typeToTypeNode(type, enclosingDeclaration);
+                    var property = ts.createProperty(
+                    /*decorators*/ undefined, modifiers, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeNode, 
+                    /*initializer*/ undefined);
+                    return property;
+                case 150 /* MethodSignature */:
+                case 151 /* MethodDeclaration */:
+                    // The signature for the implementation appears as an entry in `signatures` iff
+                    // there is only one signature.
+                    // If there are overloads and an implementation signature, it appears as an
+                    // extra declaration that isn't a signature for `type`.
+                    // If there is more than one overload but no implementation signature
+                    // (eg: an abstract method or interface declaration), there is a 1-1
+                    // correspondence of declarations and signatures.
+                    var signatures = checker.getSignaturesOfType(type, 0 /* Call */);
+                    if (!ts.some(signatures)) {
+                        return undefined;
+                    }
+                    if (declarations.length === 1) {
+                        ts.Debug.assert(signatures.length === 1);
+                        var signature = signatures[0];
+                        return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
+                    }
+                    var signatureDeclarations = [];
+                    for (var i = 0; i < signatures.length; i++) {
+                        var signature = signatures[i];
+                        var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration);
+                        if (methodDeclaration) {
+                            signatureDeclarations.push(methodDeclaration);
+                        }
+                    }
+                    if (declarations.length > signatures.length) {
+                        var signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1]);
+                        var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
+                        if (methodDeclaration) {
+                            signatureDeclarations.push(methodDeclaration);
+                        }
+                    }
+                    else {
+                        ts.Debug.assert(declarations.length === signatures.length);
+                        var methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, optional, modifiers);
+                        signatureDeclarations.push(methodImplementingSignatures);
+                    }
+                    return signatureDeclarations;
+                default:
+                    return undefined;
+            }
+            function signatureToMethodDeclaration(signature, enclosingDeclaration, body) {
+                var signatureDeclaration = checker.signatureToSignatureDeclaration(signature, 151 /* MethodDeclaration */, enclosingDeclaration, ts.NodeBuilderFlags.SuppressAnyReturnType);
+                if (signatureDeclaration) {
+                    signatureDeclaration.decorators = undefined;
+                    signatureDeclaration.modifiers = modifiers;
+                    signatureDeclaration.name = name;
+                    signatureDeclaration.questionToken = optional ? ts.createToken(55 /* QuestionToken */) : undefined;
+                    signatureDeclaration.body = body;
+                }
+                return signatureDeclaration;
+            }
+        }
+        function createMethodFromCallExpression(callExpression, methodName, includeTypeScriptSyntax, makeStatic) {
+            var parameters = createDummyParameters(callExpression.arguments.length, /*names*/ undefined, /*minArgumentCount*/ undefined, includeTypeScriptSyntax);
+            var typeParameters;
+            if (includeTypeScriptSyntax) {
+                var typeArgCount = ts.length(callExpression.typeArguments);
+                for (var i = 0; i < typeArgCount; i++) {
+                    var name = typeArgCount < 8 ? String.fromCharCode(84 /* T */ + i) : "T" + i;
+                    var typeParameter = ts.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined);
+                    (typeParameters ? typeParameters : typeParameters = []).push(typeParameter);
+                }
+            }
+            var newMethod = ts.createMethod(
+            /*decorators*/ undefined, 
+            /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, 
+            /*asteriskToken*/ undefined, methodName, 
+            /*questionToken*/ undefined, typeParameters, parameters, 
+            /*type*/ includeTypeScriptSyntax ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, createStubbedMethodBody());
+            return newMethod;
+        }
+        codefix.createMethodFromCallExpression = createMethodFromCallExpression;
+        function createDummyParameters(argCount, names, minArgumentCount, addAnyType) {
+            var parameters = [];
+            for (var i = 0; i < argCount; i++) {
+                var newParameter = ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, 
+                /*dotDotDotToken*/ undefined, 
+                /*name*/ names && names[i] || "arg" + i, 
+                /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, 
+                /*type*/ addAnyType ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, 
+                /*initializer*/ undefined);
+                parameters.push(newParameter);
+            }
+            return parameters;
+        }
+        function createMethodImplementingSignatures(signatures, name, optional, modifiers) {
+            /** This is *a* signature with the maximal number of arguments,
+             * such that if there is a "maximal" signature without rest arguments,
+             * this is one of them.
+             */
+            var maxArgsSignature = signatures[0];
+            var minArgumentCount = signatures[0].minArgumentCount;
+            var someSigHasRestParameter = false;
+            for (var i = 0; i < signatures.length; i++) {
+                var sig = signatures[i];
+                minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
+                if (sig.hasRestParameter) {
+                    someSigHasRestParameter = true;
+                }
+                if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) {
+                    maxArgsSignature = sig;
+                }
+            }
+            var maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
+            var maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(function (symbol) { return symbol.name; });
+            var parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*addAnyType*/ true);
+            if (someSigHasRestParameter) {
+                var anyArrayType = ts.createArrayTypeNode(ts.createKeywordTypeNode(119 /* AnyKeyword */));
+                var restParameter = ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, ts.createToken(24 /* DotDotDotToken */), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", 
+                /*questionToken*/ maxNonRestArgs >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, anyArrayType, 
+                /*initializer*/ undefined);
+                parameters.push(restParameter);
+            }
+            return createStubbedMethod(modifiers, name, optional, 
+            /*typeParameters*/ undefined, parameters, 
+            /*returnType*/ undefined);
+        }
+        function createStubbedMethod(modifiers, name, optional, typeParameters, parameters, returnType) {
+            return ts.createMethod(
+            /*decorators*/ undefined, modifiers, 
+            /*asteriskToken*/ undefined, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeParameters, parameters, returnType, createStubbedMethodBody());
+        }
+        codefix.createStubbedMethod = createStubbedMethod;
+        function createStubbedMethodBody() {
+            return ts.createBlock([ts.createThrow(ts.createNew(ts.createIdentifier("Error"), 
+                /*typeArguments*/ undefined, [ts.createLiteral("Method not implemented.")]))], 
+            /*multiline*/ true);
+        }
+        function createVisibilityModifier(flags) {
+            if (flags & 4 /* Public */) {
+                return ts.createToken(114 /* PublicKeyword */);
+            }
+            else if (flags & 16 /* Protected */) {
+                return ts.createToken(113 /* ProtectedKeyword */);
+            }
+            return undefined;
+        }
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var codefix;
+    (function (codefix) {
+        codefix.registerCodeFix({
+            errorCodes: [
+                // Variable declarations
+                ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code,
+                // Variable uses
+                ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code,
+                // Parameter declarations
+                ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code,
+                ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code,
+                // Get Accessor declarations
+                ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code,
+                ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code,
+                // Set Accessor declarations
+                ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code,
+                // Property declarations
+                ts.Diagnostics.Member_0_implicitly_has_an_1_type.code,
+            ],
+            getCodeActions: getActionsForAddExplicitTypeAnnotation
+        });
+        function getActionsForAddExplicitTypeAnnotation(_a) {
+            var sourceFile = _a.sourceFile, program = _a.program, start = _a.span.start, errorCode = _a.errorCode, cancellationToken = _a.cancellationToken;
+            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
+            var writer;
+            if (ts.isInJavaScriptFile(token)) {
+                return undefined;
+            }
+            switch (token.kind) {
+                case 71 /* Identifier */:
+                case 24 /* DotDotDotToken */:
+                case 114 /* PublicKeyword */:
+                case 112 /* PrivateKeyword */:
+                case 113 /* ProtectedKeyword */:
+                case 131 /* ReadonlyKeyword */:
+                    // Allowed
+                    break;
+                default:
+                    return undefined;
+            }
+            var containingFunction = ts.getContainingFunction(token);
+            var checker = program.getTypeChecker();
+            switch (errorCode) {
+                // Variable and Property declarations
+                case ts.Diagnostics.Member_0_implicitly_has_an_1_type.code:
+                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
+                    return getCodeActionForVariableDeclaration(token.parent);
+                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code:
+                    return getCodeActionForVariableUsage(token);
+                // Parameter declarations
+                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
+                    if (ts.isSetAccessor(containingFunction)) {
+                        return getCodeActionForSetAccessor(containingFunction);
+                    }
+                // falls through
+                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
+                    return getCodeActionForParameters(token.parent);
+                // Get Accessor declarations
+                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
+                case ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
+                    return ts.isGetAccessor(containingFunction) ? getCodeActionForGetAccessor(containingFunction) : undefined;
+                // Set Accessor declarations
+                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
+                    return ts.isSetAccessor(containingFunction) ? getCodeActionForSetAccessor(containingFunction) : undefined;
+            }
+            return undefined;
+            function getCodeActionForVariableDeclaration(declaration) {
+                if (!ts.isIdentifier(declaration.name)) {
+                    return undefined;
+                }
+                var type = inferTypeForVariableFromUsage(declaration.name);
+                var typeString = type && typeToString(type, declaration);
+                if (!typeString) {
+                    return undefined;
+                }
+                return createCodeActions(declaration.name.getText(), declaration.name.getEnd(), ": " + typeString);
+            }
+            function getCodeActionForVariableUsage(token) {
+                var symbol = checker.getSymbolAtLocation(token);
+                return symbol && symbol.valueDeclaration && getCodeActionForVariableDeclaration(symbol.valueDeclaration);
+            }
+            function isApplicableFunctionForInference(declaration) {
+                switch (declaration.kind) {
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                    case 152 /* Constructor */:
+                        return true;
+                    case 186 /* FunctionExpression */:
+                        return !!declaration.name;
+                }
+                return false;
+            }
+            function getCodeActionForParameters(parameterDeclaration) {
+                if (!ts.isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) {
+                    return undefined;
+                }
+                var types = inferTypeForParametersFromUsage(containingFunction) ||
+                    ts.map(containingFunction.parameters, function (p) { return ts.isIdentifier(p.name) && inferTypeForVariableFromUsage(p.name); });
+                if (!types) {
+                    return undefined;
+                }
+                var textChanges = ts.zipWith(containingFunction.parameters, types, function (parameter, type) {
+                    if (type && !parameter.type && !parameter.initializer) {
+                        var typeString = typeToString(type, containingFunction);
+                        return typeString ? {
+                            span: { start: parameter.end, length: 0 },
+                            newText: ": " + typeString
+                        } : undefined;
+                    }
+                }).filter(function (c) { return !!c; });
+                return textChanges.length ? [{
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_parameter_types_from_usage), [parameterDeclaration.name.getText()]),
+                        changes: [{
+                                fileName: sourceFile.fileName,
+                                textChanges: textChanges
+                            }]
+                    }] : undefined;
+            }
+            function getCodeActionForSetAccessor(setAccessorDeclaration) {
+                var setAccessorParameter = setAccessorDeclaration.parameters[0];
+                if (!setAccessorParameter || !ts.isIdentifier(setAccessorDeclaration.name) || !ts.isIdentifier(setAccessorParameter.name)) {
+                    return undefined;
+                }
+                var type = inferTypeForVariableFromUsage(setAccessorDeclaration.name) ||
+                    inferTypeForVariableFromUsage(setAccessorParameter.name);
+                var typeString = type && typeToString(type, containingFunction);
+                if (!typeString) {
+                    return undefined;
+                }
+                return createCodeActions(setAccessorDeclaration.name.getText(), setAccessorParameter.name.getEnd(), ": " + typeString);
+            }
+            function getCodeActionForGetAccessor(getAccessorDeclaration) {
+                if (!ts.isIdentifier(getAccessorDeclaration.name)) {
+                    return undefined;
+                }
+                var type = inferTypeForVariableFromUsage(getAccessorDeclaration.name);
+                var typeString = type && typeToString(type, containingFunction);
+                if (!typeString) {
+                    return undefined;
+                }
+                var closeParenToken = getFirstChildOfKind(getAccessorDeclaration, sourceFile, 20 /* CloseParenToken */);
+                return createCodeActions(getAccessorDeclaration.name.getText(), closeParenToken.getEnd(), ": " + typeString);
+            }
+            function createCodeActions(name, start, typeString) {
+                return [{
+                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_type_of_0_from_usage), [name]),
+                        changes: [{
+                                fileName: sourceFile.fileName,
+                                textChanges: [{
+                                        span: { start: start, length: 0 },
+                                        newText: typeString
+                                    }]
+                            }]
+                    }];
+            }
+            function getReferences(token) {
+                var references = ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), token.getSourceFile(), token.getStart());
+                ts.Debug.assert(!!references, "Found no references!");
+                ts.Debug.assert(references.length === 1, "Found more references than expected");
+                return ts.map(references[0].references, function (r) { return ts.getTokenAtPosition(program.getSourceFile(r.fileName), r.textSpan.start, /*includeJsDocComment*/ false); });
+            }
+            function inferTypeForVariableFromUsage(token) {
+                return InferFromReference.inferTypeFromReferences(getReferences(token), checker, cancellationToken);
+            }
+            function inferTypeForParametersFromUsage(containingFunction) {
+                switch (containingFunction.kind) {
+                    case 152 /* Constructor */:
+                    case 186 /* FunctionExpression */:
+                    case 228 /* FunctionDeclaration */:
+                    case 151 /* MethodDeclaration */:
+                        var isConstructor = containingFunction.kind === 152 /* Constructor */;
+                        var searchToken = isConstructor ?
+                            getFirstChildOfKind(containingFunction, sourceFile, 123 /* ConstructorKeyword */) :
+                            containingFunction.name;
+                        if (searchToken) {
+                            return InferFromReference.inferTypeForParametersFromReferences(getReferences(searchToken), containingFunction, checker, cancellationToken);
+                        }
+                }
+            }
+            function getTypeAccessiblityWriter() {
+                if (!writer) {
+                    var str_1 = "";
+                    var typeIsAccessible_1 = true;
+                    var writeText = function (text) { return str_1 += text; };
+                    writer = {
+                        string: function () { return typeIsAccessible_1 ? str_1 : undefined; },
+                        writeKeyword: writeText,
+                        writeOperator: writeText,
+                        writePunctuation: writeText,
+                        writeSpace: writeText,
+                        writeStringLiteral: writeText,
+                        writeParameter: writeText,
+                        writeProperty: writeText,
+                        writeSymbol: writeText,
+                        writeLine: function () { return str_1 += " "; },
+                        increaseIndent: ts.noop,
+                        decreaseIndent: ts.noop,
+                        clear: function () { str_1 = ""; typeIsAccessible_1 = true; },
+                        trackSymbol: function (symbol, declaration, meaning) {
+                            if (checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility !== 0 /* Accessible */) {
+                                typeIsAccessible_1 = false;
+                            }
+                        },
+                        reportInaccessibleThisError: function () { typeIsAccessible_1 = false; },
+                        reportPrivateInBaseOfClassExpression: function () { typeIsAccessible_1 = false; },
+                    };
+                }
+                writer.clear();
+                return writer;
+            }
+            function typeToString(type, enclosingDeclaration) {
+                var writer = getTypeAccessiblityWriter();
+                checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration);
+                return writer.string();
+            }
+            function getFirstChildOfKind(node, sourcefile, kind) {
+                for (var _i = 0, _a = node.getChildren(sourcefile); _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    if (child.kind === kind)
+                        return child;
+                }
+                return undefined;
+            }
+        }
+        var InferFromReference;
+        (function (InferFromReference) {
+            function inferTypeFromReferences(references, checker, cancellationToken) {
+                var usageContext = {};
+                for (var _i = 0, references_1 = references; _i < references_1.length; _i++) {
+                    var reference = references_1[_i];
+                    cancellationToken.throwIfCancellationRequested();
+                    inferTypeFromContext(reference, checker, usageContext);
+                }
+                return getTypeFromUsageContext(usageContext, checker);
+            }
+            InferFromReference.inferTypeFromReferences = inferTypeFromReferences;
+            function inferTypeForParametersFromReferences(references, declaration, checker, cancellationToken) {
+                if (declaration.parameters) {
+                    var usageContext = {};
+                    for (var _i = 0, references_2 = references; _i < references_2.length; _i++) {
+                        var reference = references_2[_i];
+                        cancellationToken.throwIfCancellationRequested();
+                        inferTypeFromContext(reference, checker, usageContext);
+                    }
+                    var isConstructor = declaration.kind === 152 /* Constructor */;
+                    var callContexts = isConstructor ? usageContext.constructContexts : usageContext.callContexts;
+                    if (callContexts) {
+                        var paramTypes = [];
+                        for (var parameterIndex = 0; parameterIndex < declaration.parameters.length; parameterIndex++) {
+                            var types = [];
+                            var isRestParameter_1 = ts.isRestParameter(declaration.parameters[parameterIndex]);
+                            for (var _a = 0, callContexts_1 = callContexts; _a < callContexts_1.length; _a++) {
+                                var callContext = callContexts_1[_a];
+                                if (callContext.argumentTypes.length > parameterIndex) {
+                                    if (isRestParameter_1) {
+                                        types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); }));
+                                    }
+                                    else {
+                                        types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
+                                    }
+                                }
+                            }
+                            if (types.length) {
+                                var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
+                                paramTypes[parameterIndex] = isRestParameter_1 ? checker.createArrayType(type) : type;
+                            }
+                        }
+                        return paramTypes;
+                    }
+                }
+                return undefined;
+            }
+            InferFromReference.inferTypeForParametersFromReferences = inferTypeForParametersFromReferences;
+            function inferTypeFromContext(node, checker, usageContext) {
+                while (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
+                    node = node.parent;
+                }
+                switch (node.parent.kind) {
+                    case 193 /* PostfixUnaryExpression */:
+                        usageContext.isNumber = true;
+                        break;
+                    case 192 /* PrefixUnaryExpression */:
+                        inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext);
+                        break;
+                    case 194 /* BinaryExpression */:
+                        inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext);
+                        break;
+                    case 257 /* CaseClause */:
+                    case 258 /* DefaultClause */:
+                        inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext);
+                        break;
+                    case 181 /* CallExpression */:
+                    case 182 /* NewExpression */:
+                        if (node.parent.expression === node) {
+                            inferTypeFromCallExpressionContext(node.parent, checker, usageContext);
+                        }
+                        else {
+                            inferTypeFromContextualType(node, checker, usageContext);
+                        }
+                        break;
+                    case 179 /* PropertyAccessExpression */:
+                        inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext);
+                        break;
+                    case 180 /* ElementAccessExpression */:
+                        inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext);
+                        break;
+                    default:
+                        return inferTypeFromContextualType(node, checker, usageContext);
+                }
+            }
+            function inferTypeFromContextualType(node, checker, usageContext) {
+                if (ts.isPartOfExpression(node)) {
+                    addCandidateType(usageContext, checker.getContextualType(node));
+                }
+            }
+            function inferTypeFromPrefixUnaryExpressionContext(node, usageContext) {
+                switch (node.operator) {
+                    case 43 /* PlusPlusToken */:
+                    case 44 /* MinusMinusToken */:
+                    case 38 /* MinusToken */:
+                    case 52 /* TildeToken */:
+                        usageContext.isNumber = true;
+                        break;
+                    case 37 /* PlusToken */:
+                        usageContext.isNumberOrString = true;
+                        break;
+                }
+            }
+            function inferTypeFromBinaryExpressionContext(node, parent, checker, usageContext) {
+                switch (parent.operatorToken.kind) {
+                    // ExponentiationOperator
+                    case 40 /* AsteriskAsteriskToken */:
+                    // MultiplicativeOperator
+                    case 39 /* AsteriskToken */:
+                    case 41 /* SlashToken */:
+                    case 42 /* PercentToken */:
+                    // ShiftOperator
+                    case 45 /* LessThanLessThanToken */:
+                    case 46 /* GreaterThanGreaterThanToken */:
+                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
+                    // BitwiseOperator
+                    case 48 /* AmpersandToken */:
+                    case 49 /* BarToken */:
+                    case 50 /* CaretToken */:
+                    // CompoundAssignmentOperator
+                    case 60 /* MinusEqualsToken */:
+                    case 62 /* AsteriskAsteriskEqualsToken */:
+                    case 61 /* AsteriskEqualsToken */:
+                    case 63 /* SlashEqualsToken */:
+                    case 64 /* PercentEqualsToken */:
+                    case 68 /* AmpersandEqualsToken */:
+                    case 69 /* BarEqualsToken */:
+                    case 70 /* CaretEqualsToken */:
+                    case 65 /* LessThanLessThanEqualsToken */:
+                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
+                    case 66 /* GreaterThanGreaterThanEqualsToken */:
+                    // AdditiveOperator
+                    case 38 /* MinusToken */:
+                    // RelationalOperator
+                    case 27 /* LessThanToken */:
+                    case 30 /* LessThanEqualsToken */:
+                    case 29 /* GreaterThanToken */:
+                    case 31 /* GreaterThanEqualsToken */:
+                        var operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
+                        if (operandType.flags & 272 /* EnumLike */) {
+                            addCandidateType(usageContext, operandType);
+                        }
+                        else {
+                            usageContext.isNumber = true;
+                        }
+                        break;
+                    case 59 /* PlusEqualsToken */:
+                    case 37 /* PlusToken */:
+                        var otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
+                        if (otherOperandType.flags & 272 /* EnumLike */) {
+                            addCandidateType(usageContext, otherOperandType);
+                        }
+                        else if (otherOperandType.flags & 84 /* NumberLike */) {
+                            usageContext.isNumber = true;
+                        }
+                        else if (otherOperandType.flags & 262178 /* StringLike */) {
+                            usageContext.isString = true;
+                        }
+                        else {
+                            usageContext.isNumberOrString = true;
+                        }
+                        break;
+                    //  AssignmentOperators
+                    case 58 /* EqualsToken */:
+                    case 32 /* EqualsEqualsToken */:
+                    case 34 /* EqualsEqualsEqualsToken */:
+                    case 35 /* ExclamationEqualsEqualsToken */:
+                    case 33 /* ExclamationEqualsToken */:
+                        addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left));
+                        break;
+                    case 92 /* InKeyword */:
+                        if (node === parent.left) {
+                            usageContext.isString = true;
+                        }
+                        break;
+                    // LogicalOperator
+                    case 54 /* BarBarToken */:
+                        if (node === parent.left &&
+                            (node.parent.parent.kind === 226 /* VariableDeclaration */ || ts.isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) {
+                            // var x = x || {};
+                            // TODO: use getFalsyflagsOfType
+                            addCandidateType(usageContext, checker.getTypeAtLocation(parent.right));
+                        }
+                        break;
+                    case 53 /* AmpersandAmpersandToken */:
+                    case 26 /* CommaToken */:
+                    case 93 /* InstanceOfKeyword */:
+                        // nothing to infer here
+                        break;
+                }
+            }
+            function inferTypeFromSwitchStatementLabelContext(parent, checker, usageContext) {
+                addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression));
+            }
+            function inferTypeFromCallExpressionContext(parent, checker, usageContext) {
+                var callContext = {
+                    argumentTypes: [],
+                    returnType: {}
+                };
+                if (parent.arguments) {
+                    for (var _i = 0, _a = parent.arguments; _i < _a.length; _i++) {
+                        var argument = _a[_i];
+                        callContext.argumentTypes.push(checker.getTypeAtLocation(argument));
+                    }
+                }
+                inferTypeFromContext(parent, checker, callContext.returnType);
+                if (parent.kind === 181 /* CallExpression */) {
+                    (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext);
+                }
+                else {
+                    (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext);
+                }
+            }
+            function inferTypeFromPropertyAccessExpressionContext(parent, checker, usageContext) {
+                var name = ts.escapeLeadingUnderscores(parent.name.text);
+                if (!usageContext.properties) {
+                    usageContext.properties = ts.createUnderscoreEscapedMap();
+                }
+                var propertyUsageContext = usageContext.properties.get(name) || {};
+                inferTypeFromContext(parent, checker, propertyUsageContext);
+                usageContext.properties.set(name, propertyUsageContext);
+            }
+            function inferTypeFromPropertyElementExpressionContext(parent, node, checker, usageContext) {
+                if (node === parent.argumentExpression) {
+                    usageContext.isNumberOrString = true;
+                    return;
+                }
+                else {
+                    var indexType = checker.getTypeAtLocation(parent);
+                    var indexUsageContext = {};
+                    inferTypeFromContext(parent, checker, indexUsageContext);
+                    if (indexType.flags & 84 /* NumberLike */) {
+                        usageContext.numberIndexContext = indexUsageContext;
+                    }
+                    else {
+                        usageContext.stringIndexContext = indexUsageContext;
+                    }
+                }
+            }
+            function getTypeFromUsageContext(usageContext, checker) {
+                if (usageContext.isNumberOrString && !usageContext.isNumber && !usageContext.isString) {
+                    return checker.getUnionType([checker.getNumberType(), checker.getStringType()]);
+                }
+                else if (usageContext.isNumber) {
+                    return checker.getNumberType();
+                }
+                else if (usageContext.isString) {
+                    return checker.getStringType();
+                }
+                else if (usageContext.candidateTypes) {
+                    return checker.getWidenedType(checker.getUnionType(ts.map(usageContext.candidateTypes, function (t) { return checker.getBaseTypeOfLiteralType(t); }), /*subtypeReduction*/ true));
+                }
+                else if (usageContext.properties && hasCallContext(usageContext.properties.get("then"))) {
+                    var paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then").callContexts, /*isRestParameter*/ false, checker);
+                    var types = paramType.getCallSignatures().map(function (c) { return c.getReturnType(); });
+                    return checker.createPromiseType(types.length ? checker.getUnionType(types, /*subtypeReduction*/ true) : checker.getAnyType());
+                }
+                else if (usageContext.properties && hasCallContext(usageContext.properties.get("push"))) {
+                    return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push").callContexts, /*isRestParameter*/ false, checker));
+                }
+                else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) {
+                    var members_4 = ts.createUnderscoreEscapedMap();
+                    var callSignatures = [];
+                    var constructSignatures = [];
+                    var stringIndexInfo = void 0;
+                    var numberIndexInfo = void 0;
+                    if (usageContext.properties) {
+                        usageContext.properties.forEach(function (context, name) {
+                            var symbol = checker.createSymbol(4 /* Property */, name);
+                            symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType();
+                            members_4.set(name, symbol);
+                        });
+                    }
+                    if (usageContext.callContexts) {
+                        for (var _i = 0, _a = usageContext.callContexts; _i < _a.length; _i++) {
+                            var callContext = _a[_i];
+                            callSignatures.push(getSignatureFromCallContext(callContext, checker));
+                        }
+                    }
+                    if (usageContext.constructContexts) {
+                        for (var _b = 0, _c = usageContext.constructContexts; _b < _c.length; _b++) {
+                            var constructContext = _c[_b];
+                            constructSignatures.push(getSignatureFromCallContext(constructContext, checker));
+                        }
+                    }
+                    if (usageContext.numberIndexContext) {
+                        numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker), /*isReadonly*/ false);
+                    }
+                    if (usageContext.stringIndexContext) {
+                        stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker), /*isReadonly*/ false);
+                    }
+                    return checker.createAnonymousType(/*symbol*/ undefined, members_4, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
+                }
+                else {
+                    return undefined;
+                }
+            }
+            function getParameterTypeFromCallContexts(parameterIndex, callContexts, isRestParameter, checker) {
+                var types = [];
+                if (callContexts) {
+                    for (var _i = 0, callContexts_2 = callContexts; _i < callContexts_2.length; _i++) {
+                        var callContext = callContexts_2[_i];
+                        if (callContext.argumentTypes.length > parameterIndex) {
+                            if (isRestParameter) {
+                                types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); }));
+                            }
+                            else {
+                                types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
+                            }
+                        }
+                    }
+                }
+                if (types.length) {
+                    var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
+                    return isRestParameter ? checker.createArrayType(type) : type;
+                }
+                return undefined;
+            }
+            function getSignatureFromCallContext(callContext, checker) {
+                var parameters = [];
+                for (var i = 0; i < callContext.argumentTypes.length; i++) {
+                    var symbol = checker.createSymbol(1 /* FunctionScopedVariable */, ts.escapeLeadingUnderscores("arg" + i));
+                    symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i]));
+                    parameters.push(symbol);
+                }
+                var returnType = getTypeFromUsageContext(callContext.returnType, checker) || checker.getVoidType();
+                return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
+            }
+            function addCandidateType(context, type) {
+                if (type && !(type.flags & 1 /* Any */) && !(type.flags & 8192 /* Never */)) {
+                    (context.candidateTypes || (context.candidateTypes = [])).push(type);
+                }
+            }
+            function hasCallContext(usageContext) {
+                return usageContext && usageContext.callContexts;
+            }
+        })(InferFromReference || (InferFromReference = {}));
+    })(codefix = ts.codefix || (ts.codefix = {}));
+})(ts || (ts = {}));
+/// <reference path="addMissingInvocationForDecorator.ts" />
+/// <reference path="correctQualifiedNameToIndexedAccessType.ts" />
+/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
+/// <reference path="fixAddMissingMember.ts" />
+/// <reference path="fixSpelling.ts" />
+/// <reference path="fixCannotFindModule.ts" />
+/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
+/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
+/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
+/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
+/// <reference path="fixForgottenThisPropertyAccess.ts" />
+/// <reference path='fixUnusedIdentifier.ts' />
+/// <reference path='fixJSDocTypes.ts' />
+/// <reference path='importFixes.ts' />
+/// <reference path='disableJsDiagnostics.ts' />
+/// <reference path='helpers.ts' />
+/// <reference path='inferFromUsage.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var refactor;
+    (function (refactor) {
+        var annotateWithTypeFromJSDoc;
+        (function (annotateWithTypeFromJSDoc) {
+            var actionName = "annotate";
+            var annotateTypeFromJSDoc = {
+                name: "Annotate with type from JSDoc",
+                description: ts.Diagnostics.Annotate_with_type_from_JSDoc.message,
+                getEditsForAction: getEditsForAction,
+                getAvailableActions: getAvailableActions
+            };
+            refactor.registerRefactor(annotateTypeFromJSDoc);
+            function getAvailableActions(context) {
+                if (ts.isInJavaScriptFile(context.file)) {
+                    return undefined;
+                }
+                var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
+                if (hasUsableJSDoc(ts.findAncestor(node, isDeclarationWithType))) {
+                    return [{
+                            name: annotateTypeFromJSDoc.name,
+                            description: annotateTypeFromJSDoc.description,
+                            actions: [
+                                {
+                                    description: annotateTypeFromJSDoc.description,
+                                    name: actionName
+                                }
+                            ]
+                        }];
+                }
+            }
+            function hasUsableJSDoc(decl) {
+                if (!decl) {
+                    return false;
+                }
+                if (ts.isFunctionLikeDeclaration(decl)) {
+                    return decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!ts.getJSDocReturnType(decl));
+                }
+                return !decl.type && !!ts.getJSDocType(decl);
+            }
+            function getEditsForAction(context, action) {
+                if (actionName !== action) {
+                    return ts.Debug.fail("actionName !== action: " + actionName + " !== " + action);
+                }
+                var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
+                var decl = ts.findAncestor(node, isDeclarationWithType);
+                if (!decl || decl.type) {
+                    return undefined;
+                }
+                var jsdocType = ts.getJSDocType(decl);
+                var isFunctionWithJSDoc = ts.isFunctionLikeDeclaration(decl) && (ts.getJSDocReturnType(decl) || decl.parameters.some(function (p) { return !!ts.getJSDocType(p); }));
+                if (isFunctionWithJSDoc || jsdocType && decl.kind === 146 /* Parameter */) {
+                    return getEditsForFunctionAnnotation(context);
+                }
+                else if (jsdocType) {
+                    return getEditsForAnnotation(context);
+                }
+                else {
+                    ts.Debug.assert(!!refactor, "No applicable refactor found.");
+                }
+            }
+            function getEditsForAnnotation(context) {
+                var sourceFile = context.file;
+                var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
+                var decl = ts.findAncestor(token, isDeclarationWithType);
+                var jsdocType = ts.getJSDocType(decl);
+                if (!decl || !jsdocType || decl.type) {
+                    return ts.Debug.fail("!decl || !jsdocType || decl.type: !" + decl + " || !" + jsdocType + " || " + decl.type);
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                var declarationWithType = addType(decl, transformJSDocType(jsdocType));
+                ts.suppressLeadingAndTrailingTrivia(declarationWithType);
+                changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, declarationWithType);
+                return {
+                    edits: changeTracker.getChanges(),
+                    renameFilename: undefined,
+                    renameLocation: undefined
+                };
+            }
+            function getEditsForFunctionAnnotation(context) {
+                var sourceFile = context.file;
+                var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
+                var decl = ts.findAncestor(token, ts.isFunctionLikeDeclaration);
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                var functionWithType = addTypesToFunctionLike(decl);
+                ts.suppressLeadingAndTrailingTrivia(functionWithType);
+                changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, functionWithType);
+                return {
+                    edits: changeTracker.getChanges(),
+                    renameFilename: undefined,
+                    renameLocation: undefined
+                };
+            }
+            function isDeclarationWithType(node) {
+                return ts.isFunctionLikeDeclaration(node) ||
+                    node.kind === 226 /* VariableDeclaration */ ||
+                    node.kind === 146 /* Parameter */ ||
+                    node.kind === 148 /* PropertySignature */ ||
+                    node.kind === 149 /* PropertyDeclaration */;
+            }
+            function addTypesToFunctionLike(decl) {
+                var typeParameters = ts.getEffectiveTypeParameterDeclarations(decl, /*checkJSDoc*/ true);
+                var parameters = decl.parameters.map(function (p) { return ts.createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, transformJSDocType(ts.getEffectiveTypeAnnotationNode(p, /*checkJSDoc*/ true)), p.initializer); });
+                var returnType = transformJSDocType(ts.getEffectiveReturnTypeNode(decl, /*checkJSDoc*/ true));
+                switch (decl.kind) {
+                    case 228 /* FunctionDeclaration */:
+                        return ts.createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
+                    case 152 /* Constructor */:
+                        return ts.createConstructor(decl.decorators, decl.modifiers, parameters, decl.body);
+                    case 186 /* FunctionExpression */:
+                        return ts.createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
+                    case 187 /* ArrowFunction */:
+                        return ts.createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body);
+                    case 151 /* MethodDeclaration */:
+                        return ts.createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, typeParameters, parameters, returnType, decl.body);
+                    case 153 /* GetAccessor */:
+                        return ts.createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, returnType, decl.body);
+                    case 154 /* SetAccessor */:
+                        return ts.createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body);
+                    default:
+                        return ts.Debug.assertNever(decl, "Unexpected SyntaxKind: " + decl.kind);
+                }
+            }
+            function addType(decl, jsdocType) {
+                switch (decl.kind) {
+                    case 226 /* VariableDeclaration */:
+                        return ts.createVariableDeclaration(decl.name, jsdocType, decl.initializer);
+                    case 148 /* PropertySignature */:
+                        return ts.createPropertySignature(decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer);
+                    case 149 /* PropertyDeclaration */:
+                        return ts.createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer);
+                    default:
+                        return ts.Debug.fail("Unexpected SyntaxKind: " + decl.kind);
+                }
+            }
+            function transformJSDocType(node) {
+                if (node === undefined) {
+                    return undefined;
+                }
+                switch (node.kind) {
+                    case 268 /* JSDocAllType */:
+                    case 269 /* JSDocUnknownType */:
+                        return ts.createTypeReferenceNode("any", ts.emptyArray);
+                    case 272 /* JSDocOptionalType */:
+                        return transformJSDocOptionalType(node);
+                    case 271 /* JSDocNonNullableType */:
+                        return transformJSDocType(node.type);
+                    case 270 /* JSDocNullableType */:
+                        return transformJSDocNullableType(node);
+                    case 274 /* JSDocVariadicType */:
+                        return transformJSDocVariadicType(node);
+                    case 273 /* JSDocFunctionType */:
+                        return transformJSDocFunctionType(node);
+                    case 146 /* Parameter */:
+                        return transformJSDocParameter(node);
+                    case 159 /* TypeReference */:
+                        return transformJSDocTypeReference(node);
+                    default:
+                        var visited = ts.visitEachChild(node, transformJSDocType, /*context*/ undefined);
+                        ts.setEmitFlags(visited, 1 /* SingleLine */);
+                        return visited;
+                }
+            }
+            function transformJSDocOptionalType(node) {
+                return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("undefined", ts.emptyArray)]);
+            }
+            function transformJSDocNullableType(node) {
+                return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("null", ts.emptyArray)]);
+            }
+            function transformJSDocVariadicType(node) {
+                return ts.createArrayTypeNode(ts.visitNode(node.type, transformJSDocType));
+            }
+            function transformJSDocFunctionType(node) {
+                var parameters = node.parameters && node.parameters.map(transformJSDocType);
+                return ts.createFunctionTypeNode(ts.emptyArray, parameters, node.type);
+            }
+            function transformJSDocParameter(node) {
+                var index = node.parent.parameters.indexOf(node);
+                var isRest = node.type.kind === 274 /* JSDocVariadicType */ && index === node.parent.parameters.length - 1;
+                var name = node.name || (isRest ? "rest" : "arg" + index);
+                var dotdotdot = isRest ? ts.createToken(24 /* DotDotDotToken */) : node.dotDotDotToken;
+                return ts.createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, ts.visitNode(node.type, transformJSDocType), node.initializer);
+            }
+            function transformJSDocTypeReference(node) {
+                var name = node.typeName;
+                var args = node.typeArguments;
+                if (ts.isIdentifier(node.typeName)) {
+                    if (ts.isJSDocIndexSignature(node)) {
+                        return transformJSDocIndexSignature(node);
+                    }
+                    var text = node.typeName.text;
+                    switch (node.typeName.text) {
+                        case "String":
+                        case "Boolean":
+                        case "Object":
+                        case "Number":
+                            text = text.toLowerCase();
+                            break;
+                        case "array":
+                        case "date":
+                        case "promise":
+                            text = text[0].toUpperCase() + text.slice(1);
+                            break;
+                    }
+                    name = ts.createIdentifier(text);
+                    if ((text === "Array" || text === "Promise") && !node.typeArguments) {
+                        args = ts.createNodeArray([ts.createTypeReferenceNode("any", ts.emptyArray)]);
+                    }
+                    else {
+                        args = ts.visitNodes(node.typeArguments, transformJSDocType);
+                    }
+                }
+                return ts.createTypeReferenceNode(name, args);
+            }
+            function transformJSDocIndexSignature(node) {
+                var index = ts.createParameter(
+                /*decorators*/ undefined, 
+                /*modifiers*/ undefined, 
+                /*dotDotDotToken*/ undefined, node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "n" : "s", 
+                /*questionToken*/ undefined, ts.createTypeReferenceNode(node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "number" : "string", []), 
+                /*initializer*/ undefined);
+                var indexSignature = ts.createTypeLiteralNode([ts.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]);
+                ts.setEmitFlags(indexSignature, 1 /* SingleLine */);
+                return indexSignature;
+            }
+        })(annotateWithTypeFromJSDoc = refactor.annotateWithTypeFromJSDoc || (refactor.annotateWithTypeFromJSDoc = {}));
+    })(refactor = ts.refactor || (ts.refactor = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var refactor;
+    (function (refactor) {
+        var convertFunctionToES6Class;
+        (function (convertFunctionToES6Class_1) {
+            var actionName = "convert";
+            var convertFunctionToES6Class = {
+                name: "Convert to ES2015 class",
+                description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message,
+                getEditsForAction: getEditsForAction,
+                getAvailableActions: getAvailableActions
+            };
+            refactor.registerRefactor(convertFunctionToES6Class);
+            function getAvailableActions(context) {
+                if (!ts.isInJavaScriptFile(context.file)) {
+                    return undefined;
+                }
+                var symbol = getConstructorSymbol(context);
+                if (!symbol) {
+                    return undefined;
+                }
+                if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                    symbol = symbol.valueDeclaration.initializer.symbol;
+                }
+                if ((symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) {
+                    return [
+                        {
+                            name: convertFunctionToES6Class.name,
+                            description: convertFunctionToES6Class.description,
+                            actions: [
+                                {
+                                    description: convertFunctionToES6Class.description,
+                                    name: actionName
+                                }
+                            ]
+                        }
+                    ];
+                }
+            }
+            function getEditsForAction(context, action) {
+                // Somehow wrong action got invoked?
+                if (actionName !== action) {
+                    return undefined;
+                }
+                var sourceFile = context.file;
+                var ctorSymbol = getConstructorSymbol(context);
+                var newLine = context.rulesProvider.getFormatOptions().newLineCharacter;
+                var deletedNodes = [];
+                var deletes = [];
+                if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) {
+                    return undefined;
+                }
+                var ctorDeclaration = ctorSymbol.valueDeclaration;
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                var precedingNode;
+                var newClassDeclaration;
+                switch (ctorDeclaration.kind) {
+                    case 228 /* FunctionDeclaration */:
+                        precedingNode = ctorDeclaration;
+                        deleteNode(ctorDeclaration);
+                        newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration);
+                        break;
+                    case 226 /* VariableDeclaration */:
+                        precedingNode = ctorDeclaration.parent.parent;
+                        if (ctorDeclaration.parent.declarations.length === 1) {
+                            deleteNode(precedingNode);
+                        }
+                        else {
+                            deleteNode(ctorDeclaration, /*inList*/ true);
+                        }
+                        newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration);
+                        break;
+                }
+                if (!newClassDeclaration) {
+                    return undefined;
+                }
+                // Because the preceding node could be touched, we need to insert nodes before delete nodes.
+                changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine });
+                for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) {
+                    var deleteCallback = deletes_1[_i];
+                    deleteCallback();
+                }
+                return {
+                    edits: changeTracker.getChanges(),
+                    renameFilename: undefined,
+                    renameLocation: undefined,
+                };
+                function deleteNode(node, inList) {
+                    if (inList === void 0) { inList = false; }
+                    if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) {
+                        // Parent node has already been deleted; do nothing
+                        return;
+                    }
+                    deletedNodes.push(node);
+                    if (inList) {
+                        deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); });
+                    }
+                    else {
+                        deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); });
+                    }
+                }
+                function createClassElementsFromSymbol(symbol) {
+                    var memberElements = [];
+                    // all instance members are stored in the "member" array of symbol
+                    if (symbol.members) {
+                        symbol.members.forEach(function (member) {
+                            var memberElement = createClassElement(member, /*modifiers*/ undefined);
+                            if (memberElement) {
+                                memberElements.push(memberElement);
+                            }
+                        });
+                    }
+                    // all static members are stored in the "exports" array of symbol
+                    if (symbol.exports) {
+                        symbol.exports.forEach(function (member) {
+                            var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]);
+                            if (memberElement) {
+                                memberElements.push(memberElement);
+                            }
+                        });
+                    }
+                    return memberElements;
+                    function shouldConvertDeclaration(_target, source) {
+                        // Right now the only thing we can convert are function expressions - other values shouldn't get
+                        // transformed. We can update this once ES public class properties are available.
+                        return ts.isFunctionLike(source);
+                    }
+                    function createClassElement(symbol, modifiers) {
+                        // both properties and methods are bound as property symbols
+                        if (!(symbol.flags & 4 /* Property */)) {
+                            return;
+                        }
+                        var memberDeclaration = symbol.valueDeclaration;
+                        var assignmentBinaryExpression = memberDeclaration.parent;
+                        if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) {
+                            return;
+                        }
+                        // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end
+                        var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */
+                            ? assignmentBinaryExpression.parent : assignmentBinaryExpression;
+                        deleteNode(nodeToDelete);
+                        if (!assignmentBinaryExpression.right) {
+                            return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, 
+                            /*type*/ undefined, /*initializer*/ undefined);
+                        }
+                        switch (assignmentBinaryExpression.right.kind) {
+                            case 186 /* FunctionExpression */: {
+                                var functionExpression = assignmentBinaryExpression.right;
+                                var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(functionExpression, 120 /* AsyncKeyword */));
+                                var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
+                                /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
+                                copyComments(assignmentBinaryExpression, method);
+                                return method;
+                            }
+                            case 187 /* ArrowFunction */: {
+                                var arrowFunction = assignmentBinaryExpression.right;
+                                var arrowFunctionBody = arrowFunction.body;
+                                var bodyBlock = void 0;
+                                // case 1: () => { return [1,2,3] }
+                                if (arrowFunctionBody.kind === 207 /* Block */) {
+                                    bodyBlock = arrowFunctionBody;
+                                }
+                                else {
+                                    var expression = arrowFunctionBody;
+                                    bodyBlock = ts.createBlock([ts.createReturn(expression)]);
+                                }
+                                var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(arrowFunction, 120 /* AsyncKeyword */));
+                                var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
+                                /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
+                                copyComments(assignmentBinaryExpression, method);
+                                return method;
+                            }
+                            default: {
+                                // Don't try to declare members in JavaScript files
+                                if (ts.isSourceFileJavaScript(sourceFile)) {
+                                    return;
+                                }
+                                var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, 
+                                /*type*/ undefined, assignmentBinaryExpression.right);
+                                copyComments(assignmentBinaryExpression.parent, prop);
+                                return prop;
+                            }
+                        }
+                    }
+                }
+                function copyComments(sourceNode, targetNode) {
+                    ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) {
+                        if (kind === 3 /* MultiLineCommentTrivia */) {
+                            // Remove leading /*
+                            pos += 2;
+                            // Remove trailing */
+                            end -= 2;
+                        }
+                        else {
+                            // Remove leading //
+                            pos += 2;
+                        }
+                        ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl);
+                    });
+                }
+                function createClassFromVariableDeclaration(node) {
+                    var initializer = node.initializer;
+                    if (!initializer || initializer.kind !== 186 /* FunctionExpression */) {
+                        return undefined;
+                    }
+                    if (node.name.kind !== 71 /* Identifier */) {
+                        return undefined;
+                    }
+                    var memberElements = createClassElementsFromSymbol(initializer.symbol);
+                    if (initializer.body) {
+                        memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
+                    }
+                    var modifiers = getModifierKindFromSource(precedingNode, 84 /* ExportKeyword */);
+                    var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
+                    /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
+                    // Don't call copyComments here because we'll already leave them in place
+                    return cls;
+                }
+                function createClassFromFunctionDeclaration(node) {
+                    var memberElements = createClassElementsFromSymbol(ctorSymbol);
+                    if (node.body) {
+                        memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
+                    }
+                    var modifiers = getModifierKindFromSource(node, 84 /* ExportKeyword */);
+                    var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
+                    /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
+                    // Don't call copyComments here because we'll already leave them in place
+                    return cls;
+                }
+                function getModifierKindFromSource(source, kind) {
+                    return ts.filter(source.modifiers, function (modifier) { return modifier.kind === kind; });
+                }
+            }
+            function getConstructorSymbol(_a) {
+                var startPosition = _a.startPosition, file = _a.file, program = _a.program;
+                var checker = program.getTypeChecker();
+                var token = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
+                return checker.getSymbolAtLocation(token);
+            }
+        })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {}));
+    })(refactor = ts.refactor || (ts.refactor = {}));
+})(ts || (ts = {}));
+/// <reference path="../refactorProvider.ts" />
+/// <reference path="../../compiler/checker.ts" />
+/* @internal */
+var ts;
+(function (ts) {
+    var refactor;
+    (function (refactor) {
+        var extractSymbol;
+        (function (extractSymbol_1) {
+            var extractSymbol = {
+                name: "Extract Symbol",
+                description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_symbol),
+                getAvailableActions: getAvailableActions,
+                getEditsForAction: getEditsForAction,
+            };
+            refactor.registerRefactor(extractSymbol);
+            /**
+             * Compute the associated code actions
+             * Exported for tests.
+             */
+            function getAvailableActions(context) {
+                var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) });
+                var targetRange = rangeToExtract.targetRange;
+                if (targetRange === undefined) {
+                    return undefined;
+                }
+                var extractions = getPossibleExtractions(targetRange, context);
+                if (extractions === undefined) {
+                    // No extractions possible
+                    return undefined;
+                }
+                var functionActions = [];
+                var usedFunctionNames = ts.createMap();
+                var constantActions = [];
+                var usedConstantNames = ts.createMap();
+                var i = 0;
+                for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) {
+                    var _a = extractions_1[_i], functionExtraction = _a.functionExtraction, constantExtraction = _a.constantExtraction;
+                    // Skip these since we don't have a way to report errors yet
+                    if (functionExtraction.errors.length === 0) {
+                        // Don't issue refactorings with duplicated names.
+                        // Scopes come back in "innermost first" order, so extractions will
+                        // preferentially go into nearer scopes
+                        var description = functionExtraction.description;
+                        if (!usedFunctionNames.has(description)) {
+                            usedFunctionNames.set(description, true);
+                            functionActions.push({
+                                description: description,
+                                name: "function_scope_" + i
+                            });
+                        }
+                    }
+                    // Skip these since we don't have a way to report errors yet
+                    if (constantExtraction.errors.length === 0) {
+                        // Don't issue refactorings with duplicated names.
+                        // Scopes come back in "innermost first" order, so extractions will
+                        // preferentially go into nearer scopes
+                        var description = constantExtraction.description;
+                        if (!usedConstantNames.has(description)) {
+                            usedConstantNames.set(description, true);
+                            constantActions.push({
+                                description: description,
+                                name: "constant_scope_" + i
+                            });
+                        }
+                    }
+                    // *do* increment i anyway because we'll look for the i-th scope
+                    // later when actually doing the refactoring if the user requests it
+                    i++;
+                }
+                var infos = [];
+                if (functionActions.length) {
+                    infos.push({
+                        name: extractSymbol.name,
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function),
+                        actions: functionActions
+                    });
+                }
+                if (constantActions.length) {
+                    infos.push({
+                        name: extractSymbol.name,
+                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant),
+                        actions: constantActions
+                    });
+                }
+                return infos.length ? infos : undefined;
+            }
+            extractSymbol_1.getAvailableActions = getAvailableActions;
+            /* Exported for tests */
+            function getEditsForAction(context, actionName) {
+                var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) });
+                var targetRange = rangeToExtract.targetRange;
+                var parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName);
+                if (parsedFunctionIndexMatch) {
+                    var index = +parsedFunctionIndexMatch[1];
+                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index");
+                    return getFunctionExtractionAtIndex(targetRange, context, index);
+                }
+                var parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName);
+                if (parsedConstantIndexMatch) {
+                    var index = +parsedConstantIndexMatch[1];
+                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index");
+                    return getConstantExtractionAtIndex(targetRange, context, index);
+                }
+                ts.Debug.fail("Unrecognized action name");
+            }
+            extractSymbol_1.getEditsForAction = getEditsForAction;
+            // Move these into diagnostic messages if they become user-facing
+            var Messages;
+            (function (Messages) {
+                function createMessage(message) {
+                    return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message };
+                }
+                Messages.CannotExtractRange = createMessage("Cannot extract range.");
+                Messages.CannotExtractImport = createMessage("Cannot extract import statement.");
+                Messages.CannotExtractSuper = createMessage("Cannot extract super call.");
+                Messages.CannotExtractEmpty = createMessage("Cannot extract empty range.");
+                Messages.ExpressionExpected = createMessage("expression expected.");
+                Messages.UselessConstantType = createMessage("No reason to extract constant of type.");
+                Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected.");
+                Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements.");
+                Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement.");
+                Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range.");
+                Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators.");
+                Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope.");
+                Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope.");
+                Messages.CannotExtractIdentifier = createMessage("Select more than a single identifier.");
+                Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration");
+                Messages.CannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression");
+                Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
+                Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts");
+                Messages.CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes");
+                Messages.CannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function");
+                Messages.CannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS");
+                Messages.CannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block");
+            })(Messages = extractSymbol_1.Messages || (extractSymbol_1.Messages = {}));
+            var RangeFacts;
+            (function (RangeFacts) {
+                RangeFacts[RangeFacts["None"] = 0] = "None";
+                RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn";
+                RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator";
+                RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction";
+                RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis";
+                /**
+                 * The range is in a function which needs the 'static' modifier in a class
+                 */
+                RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion";
+            })(RangeFacts || (RangeFacts = {}));
+            /**
+             * getRangeToExtract takes a span inside a text file and returns either an expression or an array
+             * of statements representing the minimum set of nodes needed to extract the entire span. This
+             * process may fail, in which case a set of errors is returned instead (these are currently
+             * not shown to the user, but can be used by us diagnostically)
+             */
+            // exported only for tests
+            function getRangeToExtract(sourceFile, span) {
+                var length = span.length;
+                if (length === 0) {
+                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractEmpty)] };
+                }
+                // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
+                // This may fail (e.g. you select two statements in the root of a source file)
+                var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
+                // Do the same for the ending position
+                var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span);
+                var declarations = [];
+                // We'll modify these flags as we walk the tree to collect data
+                // about what things need to be done as part of the extraction.
+                var rangeFacts = RangeFacts.None;
+                if (!start || !end) {
+                    // cannot find either start or end node
+                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
+                }
+                if (start.parent !== end.parent) {
+                    // start and end nodes belong to different subtrees
+                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
+                }
+                if (start !== end) {
+                    // start and end should be statements and parent should be either block or a source file
+                    if (!isBlockLike(start.parent)) {
+                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
+                    }
+                    var statements = [];
+                    for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) {
+                        var statement = _a[_i];
+                        if (statement === start || statements.length) {
+                            var errors_1 = checkNode(statement);
+                            if (errors_1) {
+                                return { errors: errors_1 };
+                            }
+                            statements.push(statement);
+                        }
+                        if (statement === end) {
+                            break;
+                        }
+                    }
+                    return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } };
+                }
+                // We have a single node (start)
+                var errors = checkRootNode(start) || checkNode(start);
+                if (errors) {
+                    return { errors: errors };
+                }
+                return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
+                function checkRootNode(node) {
+                    if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) {
+                        return [ts.createDiagnosticForNode(node, Messages.CannotExtractIdentifier)];
+                    }
+                    return undefined;
+                }
+                function checkForStaticContext(nodeToCheck, containingClass) {
+                    var current = nodeToCheck;
+                    while (current !== containingClass) {
+                        if (current.kind === 149 /* PropertyDeclaration */) {
+                            if (ts.hasModifier(current, 32 /* Static */)) {
+                                rangeFacts |= RangeFacts.InStaticRegion;
+                            }
+                            break;
+                        }
+                        else if (current.kind === 146 /* Parameter */) {
+                            var ctorOrMethod = ts.getContainingFunction(current);
+                            if (ctorOrMethod.kind === 152 /* Constructor */) {
+                                rangeFacts |= RangeFacts.InStaticRegion;
+                            }
+                            break;
+                        }
+                        else if (current.kind === 151 /* MethodDeclaration */) {
+                            if (ts.hasModifier(current, 32 /* Static */)) {
+                                rangeFacts |= RangeFacts.InStaticRegion;
+                            }
+                        }
+                        current = current.parent;
+                    }
+                }
+                // Verifies whether we can actually extract this node or not.
+                function checkNode(nodeToCheck) {
+                    var PermittedJumps;
+                    (function (PermittedJumps) {
+                        PermittedJumps[PermittedJumps["None"] = 0] = "None";
+                        PermittedJumps[PermittedJumps["Break"] = 1] = "Break";
+                        PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue";
+                        PermittedJumps[PermittedJumps["Return"] = 4] = "Return";
+                    })(PermittedJumps || (PermittedJumps = {}));
+                    if (!ts.isStatement(nodeToCheck) && !(ts.isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
+                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
+                    }
+                    if (ts.isInAmbientContext(nodeToCheck)) {
+                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)];
+                    }
+                    // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default)
+                    var containingClass = ts.getContainingClass(nodeToCheck);
+                    if (containingClass) {
+                        checkForStaticContext(nodeToCheck, containingClass);
+                    }
+                    var errors;
+                    var permittedJumps = 4 /* Return */;
+                    var seenLabels;
+                    visit(nodeToCheck);
+                    return errors;
+                    function visit(node) {
+                        if (errors) {
+                            // already found an error - can stop now
+                            return true;
+                        }
+                        if (ts.isDeclaration(node)) {
+                            var declaringNode = (node.kind === 226 /* VariableDeclaration */) ? node.parent.parent : node;
+                            if (ts.hasModifier(declaringNode, 1 /* Export */)) {
+                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity));
+                                return true;
+                            }
+                            declarations.push(node.symbol);
+                        }
+                        // Some things can't be extracted in certain situations
+                        switch (node.kind) {
+                            case 238 /* ImportDeclaration */:
+                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractImport));
+                                return true;
+                            case 97 /* SuperKeyword */:
+                                // For a super *constructor call*, we have to be extracting the entire class,
+                                // but a super *method call* simply implies a 'this' reference
+                                if (node.parent.kind === 181 /* CallExpression */) {
+                                    // Super constructor call
+                                    var containingClass_1 = ts.getContainingClass(node);
+                                    if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) {
+                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractSuper));
+                                        return true;
+                                    }
+                                }
+                                else {
+                                    rangeFacts |= RangeFacts.UsesThis;
+                                }
+                                break;
+                        }
+                        if (!node || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node)) {
+                            switch (node.kind) {
+                                case 228 /* FunctionDeclaration */:
+                                case 229 /* ClassDeclaration */:
+                                    if (node.parent.kind === 265 /* SourceFile */ && node.parent.externalModuleIndicator === undefined) {
+                                        // You cannot extract global declarations
+                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope));
+                                    }
+                                    break;
+                            }
+                            // do not dive into functions or classes
+                            return false;
+                        }
+                        var savedPermittedJumps = permittedJumps;
+                        switch (node.kind) {
+                            case 211 /* IfStatement */:
+                                permittedJumps = 0 /* None */;
+                                break;
+                            case 224 /* TryStatement */:
+                                // forbid all jumps inside try blocks
+                                permittedJumps = 0 /* None */;
+                                break;
+                            case 207 /* Block */:
+                                if (node.parent && node.parent.kind === 224 /* TryStatement */ && node.parent.finallyBlock === node) {
+                                    // allow unconditional returns from finally blocks
+                                    permittedJumps = 4 /* Return */;
+                                }
+                                break;
+                            case 257 /* CaseClause */:
+                                // allow unlabeled break inside case clauses
+                                permittedJumps |= 1 /* Break */;
+                                break;
+                            default:
+                                if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) {
+                                    // allow unlabeled break/continue inside loops
+                                    permittedJumps |= 1 /* Break */ | 2 /* Continue */;
+                                }
+                                break;
+                        }
+                        switch (node.kind) {
+                            case 169 /* ThisType */:
+                            case 99 /* ThisKeyword */:
+                                rangeFacts |= RangeFacts.UsesThis;
+                                break;
+                            case 222 /* LabeledStatement */:
+                                {
+                                    var label = node.label;
+                                    (seenLabels || (seenLabels = [])).push(label.escapedText);
+                                    ts.forEachChild(node, visit);
+                                    seenLabels.pop();
+                                    break;
+                                }
+                            case 218 /* BreakStatement */:
+                            case 217 /* ContinueStatement */:
+                                {
+                                    var label = node.label;
+                                    if (label) {
+                                        if (!ts.contains(seenLabels, label.escapedText)) {
+                                            // attempts to jump to label that is not in range to be extracted
+                                            (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange));
+                                        }
+                                    }
+                                    else {
+                                        if (!(permittedJumps & (node.kind === 218 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) {
+                                            // attempt to break or continue in a forbidden context
+                                            (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements));
+                                        }
+                                    }
+                                    break;
+                                }
+                            case 191 /* AwaitExpression */:
+                                rangeFacts |= RangeFacts.IsAsyncFunction;
+                                break;
+                            case 197 /* YieldExpression */:
+                                rangeFacts |= RangeFacts.IsGenerator;
+                                break;
+                            case 219 /* ReturnStatement */:
+                                if (permittedJumps & 4 /* Return */) {
+                                    rangeFacts |= RangeFacts.HasReturn;
+                                }
+                                else {
+                                    (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement));
+                                }
+                                break;
+                            default:
+                                ts.forEachChild(node, visit);
+                                break;
+                        }
+                        permittedJumps = savedPermittedJumps;
+                    }
+                }
+            }
+            extractSymbol_1.getRangeToExtract = getRangeToExtract;
+            function getStatementOrExpressionRange(node) {
+                if (ts.isStatement(node)) {
+                    return [node];
+                }
+                else if (ts.isPartOfExpression(node)) {
+                    // If our selection is the expression in an ExpressionStatement, expand
+                    // the selection to include the enclosing Statement (this stops us
+                    // from trying to care about the return value of the extracted function
+                    // and eliminates double semicolon insertion in certain scenarios)
+                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
+                }
+                return undefined;
+            }
+            function isScope(node) {
+                return ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node);
+            }
+            /**
+             * Computes possible places we could extract the function into. For example,
+             * you may be able to extract into a class method *or* local closure *or* namespace function,
+             * depending on what's in the extracted body.
+             */
+            function collectEnclosingScopes(range) {
+                var current = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
+                if (range.facts & RangeFacts.UsesThis) {
+                    // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class
+                    var containingClass = ts.getContainingClass(current);
+                    if (containingClass) {
+                        var containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration);
+                        return containingFunction
+                            ? [containingFunction, containingClass]
+                            : [containingClass];
+                    }
+                }
+                var scopes = [];
+                while (true) {
+                    current = current.parent;
+                    // A function parameter's initializer is actually in the outer scope, not the function declaration
+                    if (current.kind === 146 /* Parameter */) {
+                        // Skip all the way to the outer scope of the function that declared this parameter
+                        current = ts.findAncestor(current, function (parent) { return ts.isFunctionLikeDeclaration(parent); }).parent;
+                    }
+                    // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of.
+                    // Walk up to the closest parent of a place where we can logically put a sibling:
+                    //  * Function declaration
+                    //  * Class declaration or expression
+                    //  * Module/namespace or source file
+                    if (isScope(current)) {
+                        scopes.push(current);
+                        if (current.kind === 265 /* SourceFile */) {
+                            return scopes;
+                        }
+                    }
+                }
+            }
+            function getFunctionExtractionAtIndex(targetRange, context, requestedChangesIndex) {
+                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, functionErrorsPerScope = _b.functionErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
+                ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
+                context.cancellationToken.throwIfCancellationRequested();
+                return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context);
+            }
+            function getConstantExtractionAtIndex(targetRange, context, requestedChangesIndex) {
+                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, constantErrorsPerScope = _b.constantErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
+                ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
+                ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?");
+                context.cancellationToken.throwIfCancellationRequested();
+                var expression = ts.isExpression(target)
+                    ? target
+                    : target.statements[0].expression;
+                return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context);
+            }
+            /**
+             * Given a piece of text to extract ('targetRange'), computes a list of possible extractions.
+             * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes
+             * or an error explaining why we can't extract into that scope.
+             */
+            function getPossibleExtractions(targetRange, context) {
+                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, functionErrorsPerScope = _b.functionErrorsPerScope, constantErrorsPerScope = _b.constantErrorsPerScope;
+                // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547
+                var extractions = scopes.map(function (scope, i) {
+                    var functionDescriptionPart = getDescriptionForFunctionInScope(scope);
+                    var constantDescriptionPart = getDescriptionForConstantInScope(scope);
+                    var scopeDescription = ts.isFunctionLikeDeclaration(scope)
+                        ? getDescriptionForFunctionLikeDeclaration(scope)
+                        : ts.isClassLike(scope)
+                            ? getDescriptionForClassLikeDeclaration(scope)
+                            : getDescriptionForModuleLikeDeclaration(scope);
+                    var functionDescription;
+                    var constantDescription;
+                    if (scopeDescription === 1 /* Global */) {
+                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]);
+                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]);
+                    }
+                    else if (scopeDescription === 0 /* Module */) {
+                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]);
+                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]);
+                    }
+                    else {
+                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]);
+                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]);
+                    }
+                    // Customize the phrasing for the innermost scope to increase clarity.
+                    if (i === 0 && !ts.isClassLike(scope)) {
+                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]);
+                    }
+                    return {
+                        functionExtraction: {
+                            description: functionDescription,
+                            errors: functionErrorsPerScope[i],
+                        },
+                        constantExtraction: {
+                            description: constantDescription,
+                            errors: constantErrorsPerScope[i],
+                        },
+                    };
+                });
+                return extractions;
+            }
+            function getPossibleExtractionsWorker(targetRange, context) {
+                var sourceFile = context.file;
+                var scopes = collectEnclosingScopes(targetRange);
+                var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile);
+                var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken);
+                return { scopes: scopes, readsAndWrites: readsAndWrites };
+            }
+            function getDescriptionForFunctionInScope(scope) {
+                return ts.isFunctionLikeDeclaration(scope)
+                    ? "inner function"
+                    : ts.isClassLike(scope)
+                        ? "method"
+                        : "function";
+            }
+            function getDescriptionForConstantInScope(scope) {
+                return ts.isClassLike(scope)
+                    ? "readonly field"
+                    : "constant";
+            }
+            function getDescriptionForFunctionLikeDeclaration(scope) {
+                switch (scope.kind) {
+                    case 152 /* Constructor */:
+                        return "constructor";
+                    case 186 /* FunctionExpression */:
+                        return scope.name
+                            ? "function expression '" + scope.name.text + "'"
+                            : "anonymous function expression";
+                    case 228 /* FunctionDeclaration */:
+                        return "function '" + scope.name.text + "'";
+                    case 187 /* ArrowFunction */:
+                        return "arrow function";
+                    case 151 /* MethodDeclaration */:
+                        return "method '" + scope.name.getText();
+                    case 153 /* GetAccessor */:
+                        return "'get " + scope.name.getText() + "'";
+                    case 154 /* SetAccessor */:
+                        return "'set " + scope.name.getText() + "'";
+                    default:
+                        ts.Debug.assertNever(scope);
+                }
+            }
+            function getDescriptionForClassLikeDeclaration(scope) {
+                return scope.kind === 229 /* ClassDeclaration */
+                    ? "class '" + scope.name.text + "'"
+                    : scope.name ? "class expression '" + scope.name.text + "'" : "anonymous class expression";
+            }
+            function getDescriptionForModuleLikeDeclaration(scope) {
+                return scope.kind === 234 /* ModuleBlock */
+                    ? "namespace '" + scope.parent.name.getText() + "'"
+                    : scope.externalModuleIndicator ? 0 /* Module */ : 1 /* Global */;
+            }
+            var SpecialScope;
+            (function (SpecialScope) {
+                SpecialScope[SpecialScope["Module"] = 0] = "Module";
+                SpecialScope[SpecialScope["Global"] = 1] = "Global";
+            })(SpecialScope || (SpecialScope = {}));
+            function getUniqueName(baseName, fileText) {
+                var nameText = baseName;
+                for (var i = 1; ts.stringContains(fileText, nameText); i++) {
+                    nameText = baseName + "_" + i;
+                }
+                return nameText;
+            }
+            /**
+             * Result of 'extractRange' operation for a specific scope.
+             * Stores either a list of changes that should be applied to extract a range or a list of errors
+             */
+            function extractFunctionInScope(node, scope, _a, exposedVariableDeclarations, range, context) {
+                var usagesInScope = _a.usages, typeParameterUsages = _a.typeParameterUsages, substitutions = _a.substitutions;
+                var checker = context.program.getTypeChecker();
+                // Make a unique name for the extracted function
+                var file = scope.getSourceFile();
+                var functionNameText = getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file.text);
+                var isJS = ts.isInJavaScriptFile(scope);
+                var functionName = ts.createIdentifier(functionNameText);
+                var returnType = undefined;
+                var parameters = [];
+                var callArguments = [];
+                var writes;
+                usagesInScope.forEach(function (usage, name) {
+                    var typeNode = undefined;
+                    if (!isJS) {
+                        var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
+                        // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
+                        type = checker.getBaseTypeOfLiteralType(type);
+                        typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation);
+                    }
+                    var paramDecl = ts.createParameter(
+                    /*decorators*/ undefined, 
+                    /*modifiers*/ undefined, 
+                    /*dotDotDotToken*/ undefined, 
+                    /*name*/ name, 
+                    /*questionToken*/ undefined, typeNode);
+                    parameters.push(paramDecl);
+                    if (usage.usage === 2 /* Write */) {
+                        (writes || (writes = [])).push(usage);
+                    }
+                    callArguments.push(ts.createIdentifier(name));
+                });
+                var typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(function (type) { return ({ type: type, declaration: getFirstDeclaration(type) }); });
+                var sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
+                var typeParameters = sortedTypeParametersAndDeclarations.length === 0
+                    ? undefined
+                    : sortedTypeParametersAndDeclarations.map(function (t) { return t.declaration; });
+                // Strictly speaking, we should check whether each name actually binds to the appropriate type
+                // parameter.  In cases of shadowing, they may not.
+                var callTypeArguments = typeParameters !== undefined
+                    ? typeParameters.map(function (decl) { return ts.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined); })
+                    : undefined;
+                // Provide explicit return types for contextually-typed functions
+                // to avoid problems when there are literal types present
+                if (ts.isExpression(node) && !isJS) {
+                    var contextualType = checker.getContextualType(node);
+                    returnType = checker.typeToTypeNode(contextualType, scope, ts.NodeBuilderFlags.NoTruncation);
+                }
+                var _b = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty;
+                ts.suppressLeadingAndTrailingTrivia(body);
+                var newFunction;
+                if (ts.isClassLike(scope)) {
+                    // always create private method in TypeScript files
+                    var modifiers = isJS ? [] : [ts.createToken(112 /* PrivateKeyword */)];
+                    if (range.facts & RangeFacts.InStaticRegion) {
+                        modifiers.push(ts.createToken(115 /* StaticKeyword */));
+                    }
+                    if (range.facts & RangeFacts.IsAsyncFunction) {
+                        modifiers.push(ts.createToken(120 /* AsyncKeyword */));
+                    }
+                    newFunction = ts.createMethod(
+                    /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, 
+                    /*questionToken*/ undefined, typeParameters, parameters, returnType, body);
+                }
+                else {
+                    newFunction = ts.createFunctionDeclaration(
+                    /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, typeParameters, parameters, returnType, body);
+                }
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                var minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end;
+                var nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope);
+                if (nodeToInsertBefore) {
+                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, { suffix: context.newLineCharacter + context.newLineCharacter });
+                }
+                else {
+                    changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, {
+                        prefix: ts.isLineBreak(file.text.charCodeAt(scope.getLastToken().pos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter,
+                        suffix: context.newLineCharacter
+                    });
+                }
+                var newNodes = [];
+                // replace range with function call
+                var called = getCalledExpression(scope, range, functionNameText);
+                var call = ts.createCall(called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference
+                callArguments);
+                if (range.facts & RangeFacts.IsGenerator) {
+                    call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call);
+                }
+                if (range.facts & RangeFacts.IsAsyncFunction) {
+                    call = ts.createAwait(call);
+                }
+                if (exposedVariableDeclarations.length && !writes) {
+                    // No need to mix declarations and writes.
+                    // How could any variables be exposed if there's a return statement?
+                    ts.Debug.assert(!returnValueProperty);
+                    ts.Debug.assert(!(range.facts & RangeFacts.HasReturn));
+                    if (exposedVariableDeclarations.length === 1) {
+                        // Declaring exactly one variable: let x = newFunction();
+                        var variableDeclaration = exposedVariableDeclarations[0];
+                        newNodes.push(ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
+                        variableDeclaration.parent.flags)));
+                    }
+                    else {
+                        // Declaring multiple variables / return properties:
+                        //   let {x, y} = newFunction();
+                        var bindingElements = [];
+                        var typeElements = [];
+                        var commonNodeFlags = exposedVariableDeclarations[0].parent.flags;
+                        var sawExplicitType = false;
+                        for (var _i = 0, exposedVariableDeclarations_1 = exposedVariableDeclarations; _i < exposedVariableDeclarations_1.length; _i++) {
+                            var variableDeclaration = exposedVariableDeclarations_1[_i];
+                            bindingElements.push(ts.createBindingElement(
+                            /*dotDotDotToken*/ undefined, 
+                            /*propertyName*/ undefined, 
+                            /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name)));
+                            // Being returned through an object literal will have widened the type.
+                            var variableType = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, ts.NodeBuilderFlags.NoTruncation);
+                            typeElements.push(ts.createPropertySignature(
+                            /*modifiers*/ undefined, 
+                            /*name*/ variableDeclaration.symbol.name, 
+                            /*questionToken*/ undefined, 
+                            /*type*/ variableType, 
+                            /*initializer*/ undefined));
+                            sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined;
+                            commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags;
+                        }
+                        var typeLiteral = sawExplicitType ? ts.createTypeLiteralNode(typeElements) : undefined;
+                        if (typeLiteral) {
+                            ts.setEmitFlags(typeLiteral, 1 /* SingleLine */);
+                        }
+                        newNodes.push(ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern(bindingElements), 
+                            /*type*/ typeLiteral, 
+                            /*initializer*/ call)], commonNodeFlags)));
+                    }
+                }
+                else if (exposedVariableDeclarations.length || writes) {
+                    if (exposedVariableDeclarations.length) {
+                        // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping.
+                        for (var _c = 0, exposedVariableDeclarations_2 = exposedVariableDeclarations; _c < exposedVariableDeclarations_2.length; _c++) {
+                            var variableDeclaration = exposedVariableDeclarations_2[_c];
+                            var flags = variableDeclaration.parent.flags;
+                            if (flags & 2 /* Const */) {
+                                flags = (flags & ~2 /* Const */) | 1 /* Let */;
+                            }
+                            newNodes.push(ts.createVariableStatement(
+                            /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags)));
+                        }
+                    }
+                    if (returnValueProperty) {
+                        // has both writes and return, need to create variable declaration to hold return value;
+                        newNodes.push(ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], 1 /* Let */)));
+                    }
+                    var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
+                    if (returnValueProperty) {
+                        assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty));
+                    }
+                    // propagate writes back
+                    if (assignments.length === 1) {
+                        // We would only have introduced a return value property if there had been
+                        // other assignments to make.
+                        ts.Debug.assert(!returnValueProperty);
+                        newNodes.push(ts.createStatement(ts.createAssignment(assignments[0].name, call)));
+                        if (range.facts & RangeFacts.HasReturn) {
+                            newNodes.push(ts.createReturn());
+                        }
+                    }
+                    else {
+                        // emit e.g.
+                        //   { a, b, __return } = newFunction(a, b);
+                        //   return __return;
+                        newNodes.push(ts.createStatement(ts.createAssignment(ts.createObjectLiteral(assignments), call)));
+                        if (returnValueProperty) {
+                            newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty)));
+                        }
+                    }
+                }
+                else {
+                    if (range.facts & RangeFacts.HasReturn) {
+                        newNodes.push(ts.createReturn(call));
+                    }
+                    else if (isReadonlyArray(range.range)) {
+                        newNodes.push(ts.createStatement(call));
+                    }
+                    else {
+                        newNodes.push(call);
+                    }
+                }
+                var replacementRange = isReadonlyArray(range.range)
+                    ? { pos: ts.first(range.range).getStart(), end: ts.last(range.range).end }
+                    : { pos: range.range.getStart(), end: range.range.end };
+                changeTracker.replaceRangeWithNodes(context.file, replacementRange, newNodes, { nodeSeparator: context.newLineCharacter });
+                var edits = changeTracker.getChanges();
+                var renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
+                var renameFilename = renameRange.getSourceFile().fileName;
+                var renameLocation = getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false);
+                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
+                function getTypeDeepCloneUnionUndefined(typeNode) {
+                    if (typeNode === undefined) {
+                        return undefined;
+                    }
+                    var clone = ts.getSynthesizedDeepClone(typeNode);
+                    var withoutParens = clone;
+                    while (ts.isParenthesizedTypeNode(withoutParens)) {
+                        withoutParens = withoutParens.type;
+                    }
+                    return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, function (t) { return t.kind === 139 /* UndefinedKeyword */; })
+                        ? clone
+                        : ts.createUnionTypeNode([clone, ts.createKeywordTypeNode(139 /* UndefinedKeyword */)]);
+                }
+            }
+            /**
+             * Result of 'extractRange' operation for a specific scope.
+             * Stores either a list of changes that should be applied to extract a range or a list of errors
+             */
+            function extractConstantInScope(node, scope, _a, rangeFacts, context) {
+                var substitutions = _a.substitutions;
+                var checker = context.program.getTypeChecker();
+                // Make a unique name for the extracted variable
+                var file = scope.getSourceFile();
+                var localNameText = getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file.text);
+                var isJS = ts.isInJavaScriptFile(scope);
+                var variableType = isJS
+                    ? undefined
+                    : checker.typeToTypeNode(checker.getContextualType(node), scope, ts.NodeBuilderFlags.NoTruncation);
+                var initializer = transformConstantInitializer(node, substitutions);
+                ts.suppressLeadingAndTrailingTrivia(initializer);
+                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
+                if (ts.isClassLike(scope)) {
+                    ts.Debug.assert(!isJS); // See CannotExtractToJSClass
+                    var modifiers = [];
+                    modifiers.push(ts.createToken(112 /* PrivateKeyword */));
+                    if (rangeFacts & RangeFacts.InStaticRegion) {
+                        modifiers.push(ts.createToken(115 /* StaticKeyword */));
+                    }
+                    modifiers.push(ts.createToken(131 /* ReadonlyKeyword */));
+                    var newVariable = ts.createProperty(
+                    /*decorators*/ undefined, modifiers, localNameText, 
+                    /*questionToken*/ undefined, variableType, initializer);
+                    var localReference = ts.createPropertyAccess(rangeFacts & RangeFacts.InStaticRegion
+                        ? ts.createIdentifier(scope.name.getText())
+                        : ts.createThis(), ts.createIdentifier(localNameText));
+                    // Declare
+                    var maxInsertionPos = node.pos;
+                    var nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope);
+                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter });
+                    // Consume
+                    changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
+                }
+                else {
+                    var newVariableDeclaration = ts.createVariableDeclaration(localNameText, variableType, initializer);
+                    // If the node is part of an initializer in a list of variable declarations, insert a new
+                    // variable declaration into the list (in case it depends on earlier ones).
+                    // CONSIDER: If the declaration list isn't const, we might want to split it into multiple
+                    // lists so that the newly extracted one can be const.
+                    var oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope);
+                    if (oldVariableDeclaration) {
+                        // Declare
+                        // CONSIDER: could detect that each is on a separate line
+                        changeTracker.insertNodeAt(context.file, oldVariableDeclaration.getStart(), newVariableDeclaration, { suffix: ", " });
+                        // Consume
+                        var localReference = ts.createIdentifier(localNameText);
+                        changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
+                    }
+                    else if (node.parent.kind === 210 /* ExpressionStatement */ && scope === ts.findAncestor(node, isScope)) {
+                        // If the parent is an expression statement and the target scope is the immediately enclosing one,
+                        // replace the statement with the declaration.
+                        var newVariableStatement = ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
+                        changeTracker.replaceRange(context.file, { pos: node.parent.getStart(), end: node.parent.end }, newVariableStatement);
+                    }
+                    else {
+                        var newVariableStatement = ts.createVariableStatement(
+                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
+                        // Declare
+                        var nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope);
+                        if (nodeToInsertBefore.pos === 0) {
+                            // If we're at the beginning of the file, we need to take care not to insert before header comments
+                            // (e.g. copyright, triple-slash references).  Fortunately, this problem has already been solved
+                            // for imports.
+                            var insertionPos = ts.getSourceFileImportLocation(file);
+                            changeTracker.insertNodeAt(context.file, insertionPos, newVariableStatement, {
+                                prefix: insertionPos === 0 ? undefined : context.newLineCharacter,
+                                suffix: ts.isLineBreak(file.text.charCodeAt(insertionPos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter
+                            });
+                        }
+                        else {
+                            changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, { suffix: context.newLineCharacter + context.newLineCharacter });
+                        }
+                        // Consume
+                        if (node.parent.kind === 210 /* ExpressionStatement */) {
+                            // If the parent is an expression statement, delete it.
+                            changeTracker.deleteRange(context.file, { pos: node.parent.getStart(), end: node.parent.end });
+                        }
+                        else {
+                            var localReference = ts.createIdentifier(localNameText);
+                            changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
+                        }
+                    }
+                }
+                var edits = changeTracker.getChanges();
+                var renameFilename = node.getSourceFile().fileName;
+                var renameLocation = getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true);
+                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
+            }
+            function getContainingVariableDeclarationIfInList(node, scope) {
+                var prevNode = undefined;
+                while (node !== undefined && node !== scope) {
+                    if (ts.isVariableDeclaration(node) &&
+                        node.initializer === prevNode &&
+                        ts.isVariableDeclarationList(node.parent) &&
+                        node.parent.declarations.length > 1) {
+                        return node;
+                    }
+                    prevNode = node;
+                    node = node.parent;
+                }
+            }
+            /**
+             * @return The index of the (only) reference to the extracted symbol.  We want the cursor
+             * to be on the reference, rather than the declaration, because it's closer to where the
+             * user was before extracting it.
+             */
+            function getRenameLocation(edits, renameFilename, functionNameText, isDeclaredBeforeUse) {
+                var delta = 0;
+                var lastPos = -1;
+                for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
+                    var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges;
+                    ts.Debug.assert(fileName === renameFilename);
+                    for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) {
+                        var change = textChanges_2[_b];
+                        var span_17 = change.span, newText = change.newText;
+                        var index = newText.indexOf(functionNameText);
+                        if (index !== -1) {
+                            lastPos = span_17.start + delta + index;
+                            // If the reference comes first, return immediately.
+                            if (!isDeclaredBeforeUse) {
+                                return lastPos;
+                            }
+                        }
+                        delta += newText.length - span_17.length;
+                    }
+                }
+                // If the declaration comes first, return the position of the last occurrence.
+                ts.Debug.assert(isDeclaredBeforeUse);
+                ts.Debug.assert(lastPos >= 0);
+                return lastPos;
+            }
+            function getFirstDeclaration(type) {
+                var firstDeclaration = undefined;
+                var symbol = type.symbol;
+                if (symbol && symbol.declarations) {
+                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
+                        var declaration = _a[_i];
+                        if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) {
+                            firstDeclaration = declaration;
+                        }
+                    }
+                }
+                return firstDeclaration;
+            }
+            function compareTypesByDeclarationOrder(_a, _b) {
+                var type1 = _a.type, declaration1 = _a.declaration;
+                var type2 = _b.type, declaration2 = _b.declaration;
+                if (declaration1) {
+                    if (declaration2) {
+                        var positionDiff = declaration1.pos - declaration2.pos;
+                        if (positionDiff !== 0) {
+                            return positionDiff;
+                        }
+                    }
+                    else {
+                        return 1; // Sort undeclared type parameters to the front.
+                    }
+                }
+                else if (declaration2) {
+                    return -1; // Sort undeclared type parameters to the front.
+                }
+                var name1 = type1.symbol ? type1.symbol.getName() : "";
+                var name2 = type2.symbol ? type2.symbol.getName() : "";
+                var nameDiff = ts.compareStrings(name1, name2);
+                if (nameDiff !== 0) {
+                    return nameDiff;
+                }
+                // IDs are guaranteed to be unique, so this ensures a total ordering.
+                return type1.id - type2.id;
+            }
+            function getCalledExpression(scope, range, functionNameText) {
+                var functionReference = ts.createIdentifier(functionNameText);
+                if (ts.isClassLike(scope)) {
+                    var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis();
+                    return ts.createPropertyAccess(lhs, functionReference);
+                }
+                else {
+                    return functionReference;
+                }
+            }
+            function transformFunctionBody(body, exposedVariableDeclarations, writes, substitutions, hasReturn) {
+                var hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0;
+                if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) {
+                    // already block, no declarations or writes to propagate back, no substitutions - can use node as is
+                    return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
+                }
+                var returnValueProperty;
+                var ignoreReturns = false;
+                var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]);
+                // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
+                if (hasWritesOrVariableDeclarations || substitutions.size) {
+                    var rewrittenStatements = ts.visitNodes(statements, visitor).slice();
+                    if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) {
+                        // add return at the end to propagate writes back in case if control flow falls out of the function body
+                        // it is ok to know that range has at least one return since it we only allow unconditional returns
+                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
+                        if (assignments.length === 1) {
+                            rewrittenStatements.push(ts.createReturn(assignments[0].name));
+                        }
+                        else {
+                            rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments)));
+                        }
+                    }
+                    return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty };
+                }
+                else {
+                    return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
+                }
+                function visitor(node) {
+                    if (!ignoreReturns && node.kind === 219 /* ReturnStatement */ && hasWritesOrVariableDeclarations) {
+                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
+                        if (node.expression) {
+                            if (!returnValueProperty) {
+                                returnValueProperty = "__return";
+                            }
+                            assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor)));
+                        }
+                        if (assignments.length === 1) {
+                            return ts.createReturn(assignments[0].name);
+                        }
+                        else {
+                            return ts.createReturn(ts.createObjectLiteral(assignments));
+                        }
+                    }
+                    else {
+                        var oldIgnoreReturns = ignoreReturns;
+                        ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node);
+                        var substitution = substitutions.get(ts.getNodeId(node).toString());
+                        var result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
+                        ignoreReturns = oldIgnoreReturns;
+                        return result;
+                    }
+                }
+            }
+            function transformConstantInitializer(initializer, substitutions) {
+                return substitutions.size
+                    ? visitor(initializer)
+                    : initializer;
+                function visitor(node) {
+                    var substitution = substitutions.get(ts.getNodeId(node).toString());
+                    return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
+                }
+            }
+            function getStatementsOrClassElements(scope) {
+                if (ts.isFunctionLikeDeclaration(scope)) {
+                    var body = scope.body;
+                    if (ts.isBlock(body)) {
+                        return body.statements;
+                    }
+                }
+                else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) {
+                    return scope.statements;
+                }
+                else if (ts.isClassLike(scope)) {
+                    return scope.members;
+                }
+                else {
+                    ts.assertTypeIsNever(scope);
+                }
+                return ts.emptyArray;
+            }
+            /**
+             * If `scope` contains a function after `minPos`, then return the first such function.
+             * Otherwise, return `undefined`.
+             */
+            function getNodeToInsertFunctionBefore(minPos, scope) {
+                return ts.find(getStatementsOrClassElements(scope), function (child) {
+                    return child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child);
+                });
+            }
+            function getNodeToInsertPropertyBefore(maxPos, scope) {
+                var members = scope.members;
+                ts.Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one.
+                var prevMember = undefined;
+                var allProperties = true;
+                for (var _i = 0, members_5 = members; _i < members_5.length; _i++) {
+                    var member = members_5[_i];
+                    if (member.pos > maxPos) {
+                        return prevMember || members[0];
+                    }
+                    if (allProperties && !ts.isPropertyDeclaration(member)) {
+                        // If it is non-vacuously true that all preceding members are properties,
+                        // insert before the current member (i.e. at the end of the list of properties).
+                        if (prevMember !== undefined) {
+                            return member;
+                        }
+                        allProperties = false;
+                    }
+                    prevMember = member;
+                }
+                ts.Debug.assert(prevMember !== undefined); // If the loop didn't return, then it did set prevMember.
+                return prevMember;
+            }
+            function getNodeToInsertConstantBefore(node, scope) {
+                ts.Debug.assert(!ts.isClassLike(scope));
+                var prevScope = undefined;
+                for (var curr = node; curr !== scope; curr = curr.parent) {
+                    if (isScope(curr)) {
+                        prevScope = curr;
+                    }
+                }
+                for (var curr = (prevScope || node).parent;; curr = curr.parent) {
+                    if (isBlockLike(curr)) {
+                        var prevStatement = undefined;
+                        for (var _i = 0, _a = curr.statements; _i < _a.length; _i++) {
+                            var statement = _a[_i];
+                            if (statement.pos > node.pos) {
+                                break;
+                            }
+                            prevStatement = statement;
+                        }
+                        // There must be at least one statement since we started in one.
+                        ts.Debug.assert(prevStatement !== undefined);
+                        return prevStatement;
+                    }
+                    if (curr === scope) {
+                        ts.Debug.fail("Didn't encounter a block-like before encountering scope");
+                        break;
+                    }
+                }
+            }
+            function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) {
+                var variableAssignments = ts.map(exposedVariableDeclarations, function (v) { return ts.createShorthandPropertyAssignment(v.symbol.name); });
+                var writeAssignments = ts.map(writes, function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); });
+                return variableAssignments === undefined
+                    ? writeAssignments
+                    : writeAssignments === undefined
+                        ? variableAssignments
+                        : variableAssignments.concat(writeAssignments);
+            }
+            function isReadonlyArray(v) {
+                return ts.isArray(v);
+            }
+            /**
+             * Produces a range that spans the entirety of nodes, given a selection
+             * that might start/end in the middle of nodes.
+             *
+             * For example, when the user makes a selection like this
+             *                     v---v
+             *   var someThing = foo + bar;
+             *  this returns     ^-------^
+             */
+            function getEnclosingTextRange(targetRange, sourceFile) {
+                return isReadonlyArray(targetRange.range)
+                    ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() }
+                    : targetRange.range;
+            }
+            var Usage;
+            (function (Usage) {
+                // value should be passed to extracted method
+                Usage[Usage["Read"] = 1] = "Read";
+                // value should be passed to extracted method and propagated back
+                Usage[Usage["Write"] = 2] = "Write";
+            })(Usage || (Usage = {}));
+            function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker, cancellationToken) {
+                var allTypeParameterUsages = ts.createMap(); // Key is type ID
+                var usagesPerScope = [];
+                var substitutionsPerScope = [];
+                var functionErrorsPerScope = [];
+                var constantErrorsPerScope = [];
+                var visibleDeclarationsInExtractedRange = [];
+                var exposedVariableSymbolSet = ts.createMap(); // Key is symbol ID
+                var exposedVariableDeclarations = [];
+                var firstExposedNonVariableDeclaration = undefined;
+                var expression = !isReadonlyArray(targetRange.range)
+                    ? targetRange.range
+                    : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0])
+                        ? targetRange.range[0].expression
+                        : undefined;
+                var expressionDiagnostic = undefined;
+                if (expression === undefined) {
+                    var statements = targetRange.range;
+                    var start = ts.first(statements).getStart();
+                    var end = ts.last(statements).end;
+                    expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected);
+                }
+                else if (checker.getTypeAtLocation(expression).flags & (1024 /* Void */ | 8192 /* Never */)) {
+                    expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.UselessConstantType);
+                }
+                // initialize results
+                for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) {
+                    var scope = scopes_1[_i];
+                    usagesPerScope.push({ usages: ts.createMap(), typeParameterUsages: ts.createMap(), substitutions: ts.createMap() });
+                    substitutionsPerScope.push(ts.createMap());
+                    functionErrorsPerScope.push(ts.isFunctionLikeDeclaration(scope) && scope.kind !== 228 /* FunctionDeclaration */
+                        ? [ts.createDiagnosticForNode(scope, Messages.CannotExtractToOtherFunctionLike)]
+                        : []);
+                    var constantErrors = [];
+                    if (expressionDiagnostic) {
+                        constantErrors.push(expressionDiagnostic);
+                    }
+                    if (ts.isClassLike(scope) && ts.isInJavaScriptFile(scope)) {
+                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.CannotExtractToJSClass));
+                    }
+                    if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) {
+                        // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this
+                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.CannotExtractToExpressionArrowFunction));
+                    }
+                    constantErrorsPerScope.push(constantErrors);
+                }
+                var seenUsages = ts.createMap();
+                var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range;
+                var unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range;
+                var inGenericContext = isInGenericContext(unmodifiedNode);
+                collectUsages(target);
+                // Unfortunately, this code takes advantage of the knowledge that the generated method
+                // will use the contextual type of an expression as the return type of the extracted
+                // method (and will therefore "use" all the types involved).
+                if (inGenericContext && !isReadonlyArray(targetRange.range)) {
+                    var contextualType = checker.getContextualType(targetRange.range);
+                    recordTypeParameterUsages(contextualType);
+                }
+                if (allTypeParameterUsages.size > 0) {
+                    var seenTypeParameterUsages = ts.createMap(); // Key is type ID
+                    var i_1 = 0;
+                    for (var curr = unmodifiedNode; curr !== undefined && i_1 < scopes.length; curr = curr.parent) {
+                        if (curr === scopes[i_1]) {
+                            // Copy current contents of seenTypeParameterUsages into scope.
+                            seenTypeParameterUsages.forEach(function (typeParameter, id) {
+                                usagesPerScope[i_1].typeParameterUsages.set(id, typeParameter);
+                            });
+                            i_1++;
+                        }
+                        // Note that we add the current node's type parameters *after* updating the corresponding scope.
+                        if (ts.isDeclarationWithTypeParameters(curr) && curr.typeParameters) {
+                            for (var _a = 0, _b = curr.typeParameters; _a < _b.length; _a++) {
+                                var typeParameterDecl = _b[_a];
+                                var typeParameter = checker.getTypeAtLocation(typeParameterDecl);
+                                if (allTypeParameterUsages.has(typeParameter.id.toString())) {
+                                    seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter);
+                                }
+                            }
+                        }
+                    }
+                    // If we didn't get through all the scopes, then there were some that weren't in our
+                    // parent chain (impossible at time of writing).  A conservative solution would be to
+                    // copy allTypeParameterUsages into all remaining scopes.
+                    ts.Debug.assert(i_1 === scopes.length);
+                }
+                // If there are any declarations in the extracted block that are used in the same enclosing
+                // lexical scope, we can't move the extraction "up" as those declarations will become unreachable
+                if (visibleDeclarationsInExtractedRange.length) {
+                    var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent)
+                        ? scopes[0]
+                        : ts.getEnclosingBlockScopeContainer(scopes[0]);
+                    ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations);
+                }
+                var _loop_8 = function (i) {
+                    var scopeUsages = usagesPerScope[i];
+                    // Special case: in the innermost scope, all usages are available.
+                    // (The computed value reflects the value at the top-level of the scope, but the
+                    // local will actually be declared at the same level as the extracted expression).
+                    if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) {
+                        var errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range;
+                        constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.CannotAccessVariablesFromNestedScopes));
+                    }
+                    var hasWrite = false;
+                    var readonlyClassPropertyWrite = undefined;
+                    usagesPerScope[i].usages.forEach(function (value) {
+                        if (value.usage === 2 /* Write */) {
+                            hasWrite = true;
+                            if (value.symbol.flags & 106500 /* ClassMember */ &&
+                                value.symbol.valueDeclaration &&
+                                ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) {
+                                readonlyClassPropertyWrite = value.symbol.valueDeclaration;
+                            }
+                        }
+                    });
+                    // If an expression was extracted, then there shouldn't have been any variable declarations.
+                    ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0);
+                    if (hasWrite && !isReadonlyArray(targetRange.range)) {
+                        var diag = ts.createDiagnosticForNode(targetRange.range, Messages.CannotWriteInExpression);
+                        functionErrorsPerScope[i].push(diag);
+                        constantErrorsPerScope[i].push(diag);
+                    }
+                    else if (readonlyClassPropertyWrite && i > 0) {
+                        var diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor);
+                        functionErrorsPerScope[i].push(diag);
+                        constantErrorsPerScope[i].push(diag);
+                    }
+                    else if (firstExposedNonVariableDeclaration) {
+                        var diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.CannotExtractExportedEntity);
+                        functionErrorsPerScope[i].push(diag);
+                        constantErrorsPerScope[i].push(diag);
+                    }
+                };
+                for (var i = 0; i < scopes.length; i++) {
+                    _loop_8(i);
+                }
+                return { target: target, usagesPerScope: usagesPerScope, functionErrorsPerScope: functionErrorsPerScope, constantErrorsPerScope: constantErrorsPerScope, exposedVariableDeclarations: exposedVariableDeclarations };
+                function hasTypeParameters(node) {
+                    return ts.isDeclarationWithTypeParameters(node) &&
+                        node.typeParameters !== undefined &&
+                        node.typeParameters.length > 0;
+                }
+                function isInGenericContext(node) {
+                    for (; node; node = node.parent) {
+                        if (hasTypeParameters(node)) {
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+                function recordTypeParameterUsages(type) {
+                    // PERF: This is potentially very expensive.  `type` could be a library type with
+                    // a lot of properties, each of which the walker will visit.  Unfortunately, the
+                    // solution isn't as trivial as filtering to user types because of (e.g.) Array.
+                    var symbolWalker = checker.getSymbolWalker(function () { return (cancellationToken.throwIfCancellationRequested(), true); });
+                    var visitedTypes = symbolWalker.walkType(type).visitedTypes;
+                    for (var _i = 0, visitedTypes_1 = visitedTypes; _i < visitedTypes_1.length; _i++) {
+                        var visitedType = visitedTypes_1[_i];
+                        if (visitedType.flags & 16384 /* TypeParameter */) {
+                            allTypeParameterUsages.set(visitedType.id.toString(), visitedType);
+                        }
+                    }
+                }
+                function collectUsages(node, valueUsage) {
+                    if (valueUsage === void 0) { valueUsage = 1 /* Read */; }
+                    if (inGenericContext) {
+                        var type = checker.getTypeAtLocation(node);
+                        recordTypeParameterUsages(type);
+                    }
+                    if (ts.isDeclaration(node) && node.symbol) {
+                        visibleDeclarationsInExtractedRange.push(node);
+                    }
+                    if (ts.isAssignmentExpression(node)) {
+                        // use 'write' as default usage for values
+                        collectUsages(node.left, 2 /* Write */);
+                        collectUsages(node.right);
+                    }
+                    else if (ts.isUnaryExpressionWithWrite(node)) {
+                        collectUsages(node.operand, 2 /* Write */);
+                    }
+                    else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
+                        // use 'write' as default usage for values
+                        ts.forEachChild(node, collectUsages);
+                    }
+                    else if (ts.isIdentifier(node)) {
+                        if (!node.parent) {
+                            return;
+                        }
+                        if (ts.isQualifiedName(node.parent) && node !== node.parent.left) {
+                            return;
+                        }
+                        if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) {
+                            return;
+                        }
+                        recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node));
+                    }
+                    else {
+                        ts.forEachChild(node, collectUsages);
+                    }
+                }
+                function recordUsage(n, usage, isTypeNode) {
+                    var symbolId = recordUsagebySymbol(n, usage, isTypeNode);
+                    if (symbolId) {
+                        for (var i = 0; i < scopes.length; i++) {
+                            // push substitution from map<symbolId, subst> to map<nodeId, subst> to simplify rewriting
+                            var substitution = substitutionsPerScope[i].get(symbolId);
+                            if (substitution) {
+                                usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution);
+                            }
+                        }
+                    }
+                }
+                function recordUsagebySymbol(identifier, usage, isTypeName) {
+                    var symbol = getSymbolReferencedByIdentifier(identifier);
+                    if (!symbol) {
+                        // cannot find symbol - do nothing
+                        return undefined;
+                    }
+                    var symbolId = ts.getSymbolId(symbol).toString();
+                    var lastUsage = seenUsages.get(symbolId);
+                    // there are two kinds of value usages
+                    // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter
+                    // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and
+                    //   returned as a return value
+                    // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read'
+                    // since all information is already recorded
+                    if (lastUsage && lastUsage >= usage) {
+                        return symbolId;
+                    }
+                    seenUsages.set(symbolId, usage);
+                    if (lastUsage) {
+                        // if we get here this means that we are trying to handle 'write' and 'read' was already processed
+                        // walk scopes and update existing records.
+                        for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) {
+                            var perScope = usagesPerScope_1[_i];
+                            var prevEntry = perScope.usages.get(identifier.text);
+                            if (prevEntry) {
+                                perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
+                            }
+                        }
+                        return symbolId;
+                    }
+                    // find first declaration in this file
+                    var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; });
+                    if (!declInFile) {
+                        return undefined;
+                    }
+                    if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) {
+                        // declaration is located in range to be extracted - do nothing
+                        return undefined;
+                    }
+                    if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) {
+                        // this is write to a reference located outside of the target scope and range is extracted into generator
+                        // currently this is unsupported scenario
+                        var diag = ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators);
+                        for (var _a = 0, functionErrorsPerScope_1 = functionErrorsPerScope; _a < functionErrorsPerScope_1.length; _a++) {
+                            var errors = functionErrorsPerScope_1[_a];
+                            errors.push(diag);
+                        }
+                        for (var _b = 0, constantErrorsPerScope_1 = constantErrorsPerScope; _b < constantErrorsPerScope_1.length; _b++) {
+                            var errors = constantErrorsPerScope_1[_b];
+                            errors.push(diag);
+                        }
+                    }
+                    for (var i = 0; i < scopes.length; i++) {
+                        var scope = scopes[i];
+                        var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags);
+                        if (resolvedSymbol === symbol) {
+                            continue;
+                        }
+                        if (!substitutionsPerScope[i].has(symbolId)) {
+                            var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName);
+                            if (substitution) {
+                                substitutionsPerScope[i].set(symbolId, substitution);
+                            }
+                            else if (isTypeName) {
+                                // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument
+                                // so there's no problem.
+                                if (!(symbol.flags & 262144 /* TypeParameter */)) {
+                                    var diag = ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope);
+                                    functionErrorsPerScope[i].push(diag);
+                                    constantErrorsPerScope[i].push(diag);
+                                }
+                            }
+                            else {
+                                usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
+                            }
+                        }
+                    }
+                    return symbolId;
+                }
+                function checkForUsedDeclarations(node) {
+                    // If this node is entirely within the original extraction range, we don't need to do anything.
+                    if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) {
+                        return;
+                    }
+                    // Otherwise check and recurse.
+                    var sym = ts.isIdentifier(node)
+                        ? getSymbolReferencedByIdentifier(node)
+                        : checker.getSymbolAtLocation(node);
+                    if (sym) {
+                        var decl = ts.find(visibleDeclarationsInExtractedRange, function (d) { return d.symbol === sym; });
+                        if (decl) {
+                            if (ts.isVariableDeclaration(decl)) {
+                                var idString = decl.symbol.id.toString();
+                                if (!exposedVariableSymbolSet.has(idString)) {
+                                    exposedVariableDeclarations.push(decl);
+                                    exposedVariableSymbolSet.set(idString, true);
+                                }
+                            }
+                            else {
+                                // CONSIDER: this includes binding elements, which we could
+                                // expose in the same way as variables.
+                                firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl;
+                            }
+                        }
+                    }
+                    ts.forEachChild(node, checkForUsedDeclarations);
+                }
+                /**
+                 * Return the symbol referenced by an identifier (even if it declares a different symbol).
+                 */
+                function getSymbolReferencedByIdentifier(identifier) {
+                    // If the identifier is both a property name and its value, we're only interested in its value
+                    // (since the name is a declaration and will be included in the extracted range).
+                    return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier
+                        ? checker.getShorthandAssignmentValueSymbol(identifier.parent)
+                        : checker.getSymbolAtLocation(identifier);
+                }
+                function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) {
+                    if (!symbol) {
+                        return undefined;
+                    }
+                    if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) {
+                        return ts.createIdentifier(symbol.name);
+                    }
+                    var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode);
+                    if (prefix === undefined) {
+                        return undefined;
+                    }
+                    return isTypeNode
+                        ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name))
+                        : ts.createPropertyAccess(prefix, symbol.name);
+                }
+            }
+            function getParentNodeInSpan(node, file, span) {
+                if (!node)
+                    return undefined;
+                while (node.parent) {
+                    if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) {
+                        return node;
+                    }
+                    node = node.parent;
+                }
+            }
+            function spanContainsNode(span, node, file) {
+                return ts.textSpanContainsPosition(span, node.getStart(file)) &&
+                    node.getEnd() <= ts.textSpanEnd(span);
+            }
+            /**
+             * Computes whether or not a node represents an expression in a position where it could
+             * be extracted.
+             * The isExpression() in utilities.ts returns some false positives we need to handle,
+             * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression
+             * in the sense of something that you could extract on
+             */
+            function isExtractableExpression(node) {
+                switch (node.parent.kind) {
+                    case 264 /* EnumMember */:
+                        return false;
+                }
+                switch (node.kind) {
+                    case 9 /* StringLiteral */:
+                        return node.parent.kind !== 238 /* ImportDeclaration */ &&
+                            node.parent.kind !== 242 /* ImportSpecifier */;
+                    case 198 /* SpreadElement */:
+                    case 174 /* ObjectBindingPattern */:
+                    case 176 /* BindingElement */:
+                        return false;
+                    case 71 /* Identifier */:
+                        return node.parent.kind !== 176 /* BindingElement */ &&
+                            node.parent.kind !== 242 /* ImportSpecifier */ &&
+                            node.parent.kind !== 246 /* ExportSpecifier */;
+                }
+                return true;
+            }
+            function isBlockLike(node) {
+                switch (node.kind) {
+                    case 207 /* Block */:
+                    case 265 /* SourceFile */:
+                    case 234 /* ModuleBlock */:
+                    case 257 /* CaseClause */:
+                        return true;
+                    default:
+                        return false;
+                }
+            }
+        })(extractSymbol = refactor.extractSymbol || (refactor.extractSymbol = {}));
+    })(refactor = ts.refactor || (ts.refactor = {}));
+})(ts || (ts = {}));
+/* @internal */
+var ts;
+(function (ts) {
+    var refactor;
+    (function (refactor) {
+        var installTypesForPackage;
+        (function (installTypesForPackage_1) {
+            var actionName = "install";
+            var installTypesForPackage = {
+                name: "Install missing types package",
+                description: "Install missing types package",
+                getEditsForAction: getEditsForAction,
+                getAvailableActions: getAvailableActions,
+            };
+            refactor.registerRefactor(installTypesForPackage);
+            function getAvailableActions(context) {
+                var options = context.program.getCompilerOptions();
+                var noImplicitAny = options.noImplicitAny === undefined ? options.strict : options.noImplicitAny;
+                if (noImplicitAny) {
+                    // Then it will be available via `fixCannotFindModule`.
+                    return undefined;
+                }
+                var action = getAction(context);
+                return action && [
+                    {
+                        name: installTypesForPackage.name,
+                        description: installTypesForPackage.description,
+                        actions: [
+                            {
+                                description: action.description,
+                                name: actionName,
+                            },
+                        ],
+                    },
+                ];
+            }
+            function getEditsForAction(context, _actionName) {
+                ts.Debug.assertEqual(actionName, _actionName);
+                var action = getAction(context); // Should be defined if we said there was an action available.
+                return {
+                    edits: [],
+                    renameFilename: undefined,
+                    renameLocation: undefined,
+                    commands: action.commands,
+                };
+            }
+            function getAction(context) {
+                var file = context.file, startPosition = context.startPosition;
+                var node = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
+                if (ts.isStringLiteral(node) && isModuleIdentifier(node) && ts.getResolvedModule(file, node.text) === undefined) {
+                    return ts.codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
+                }
+            }
+            function isModuleIdentifier(node) {
+                switch (node.parent.kind) {
+                    case 238 /* ImportDeclaration */:
+                    case 248 /* ExternalModuleReference */:
+                        return true;
+                    default:
+                        return false;
+                }
+            }
+        })(installTypesForPackage = refactor.installTypesForPackage || (refactor.installTypesForPackage = {}));
+    })(refactor = ts.refactor || (ts.refactor = {}));
+})(ts || (ts = {}));
+/// <reference path="annotateWithTypeFromJSDoc.ts" />
+/// <reference path="convertFunctionToEs6Class.ts" />
+/// <reference path="extractSymbol.ts" />
+/// <reference path="installTypesForPackage.ts" />
+/// <reference path="..\compiler\program.ts"/>
+/// <reference path="..\compiler\commandLineParser.ts"/>
+/// <reference path='types.ts' />
+/// <reference path='utilities.ts' />
+/// <reference path='breakpoints.ts' />
+/// <reference path='classifier.ts' />
+/// <reference path='completions.ts' />
+/// <reference path='documentHighlights.ts' />
+/// <reference path='documentRegistry.ts' />
+/// <reference path='findAllReferences.ts' />
+/// <reference path='goToDefinition.ts' />
+/// <reference path='jsDoc.ts' />
+/// <reference path='jsTyping.ts' />
+/// <reference path='navigateTo.ts' />
+/// <reference path='navigationBar.ts' />
+/// <reference path='outliningElementsCollector.ts' />
+/// <reference path='patternMatcher.ts' />
+/// <reference path='preProcess.ts' />
+/// <reference path='rename.ts' />
+/// <reference path='signatureHelp.ts' />
+/// <reference path='symbolDisplay.ts' />
+/// <reference path='transpile.ts' />
+/// <reference path='formatting\formatting.ts' />
+/// <reference path='formatting\smartIndenter.ts' />
+/// <reference path='textChanges.ts' />
+/// <reference path='codeFixProvider.ts' />
+/// <reference path='refactorProvider.ts' />
+/// <reference path='codefixes\fixes.ts' />
+/// <reference path='refactors\refactors.ts' />
+var ts;
+(function (ts) {
+    /** The version of the language service API */
+    ts.servicesVersion = "0.6";
+    /* @internal */
+    var ruleProvider;
+    function createNode(kind, pos, end, parent) {
+        var node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) :
+            kind === 71 /* Identifier */ ? new IdentifierObject(71 /* Identifier */, pos, end) :
+                new TokenObject(kind, pos, end);
+        node.parent = parent;
+        return node;
+    }
+    var NodeObject = /** @class */ (function () {
+        function NodeObject(kind, pos, end) {
+            this.pos = pos;
+            this.end = end;
+            this.flags = 0 /* None */;
+            this.transformFlags = undefined;
+            this.parent = undefined;
+            this.kind = kind;
+        }
+        NodeObject.prototype.getSourceFile = function () {
+            return ts.getSourceFileOfNode(this);
+        };
+        NodeObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
+            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
+        };
+        NodeObject.prototype.getFullStart = function () {
+            return this.pos;
+        };
+        NodeObject.prototype.getEnd = function () {
+            return this.end;
+        };
+        NodeObject.prototype.getWidth = function (sourceFile) {
+            return this.getEnd() - this.getStart(sourceFile);
+        };
+        NodeObject.prototype.getFullWidth = function () {
+            return this.end - this.pos;
+        };
+        NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
+            return this.getStart(sourceFile) - this.pos;
+        };
+        NodeObject.prototype.getFullText = function (sourceFile) {
+            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
+        };
+        NodeObject.prototype.getText = function (sourceFile) {
+            if (!sourceFile) {
+                sourceFile = this.getSourceFile();
+            }
+            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
+        };
+        NodeObject.prototype.addSyntheticNodes = function (nodes, pos, end) {
+            ts.scanner.setTextPos(pos);
+            while (pos < end) {
+                var token = ts.scanner.scan();
+                var textPos = ts.scanner.getTextPos();
+                if (textPos <= end) {
+                    nodes.push(createNode(token, pos, textPos, this));
+                }
+                pos = textPos;
+                if (token === 1 /* EndOfFileToken */) {
+                    break;
+                }
+            }
+            return pos;
+        };
+        NodeObject.prototype.createSyntaxList = function (nodes) {
+            var list = createNode(286 /* SyntaxList */, nodes.pos, nodes.end, this);
+            list._children = [];
+            var pos = nodes.pos;
+            for (var _i = 0, nodes_9 = nodes; _i < nodes_9.length; _i++) {
+                var node = nodes_9[_i];
+                if (pos < node.pos) {
+                    pos = this.addSyntheticNodes(list._children, pos, node.pos);
+                }
+                list._children.push(node);
+                pos = node.end;
+            }
+            if (pos < nodes.end) {
+                this.addSyntheticNodes(list._children, pos, nodes.end);
+            }
+            return list;
+        };
+        NodeObject.prototype.createChildren = function (sourceFile) {
+            var _this = this;
+            if (!ts.isNodeKind(this.kind)) {
+                this._children = ts.emptyArray;
+                return;
+            }
+            if (ts.isJSDocCommentContainingNode(this)) {
+                /** Don't add trivia for "tokens" since this is in a comment. */
+                var children_3 = [];
+                this.forEachChild(function (child) { children_3.push(child); });
+                this._children = children_3;
+                return;
+            }
+            var children = [];
+            ts.scanner.setText((sourceFile || this.getSourceFile()).text);
+            var pos = this.pos;
+            var processNode = function (node) {
+                pos = _this.addSyntheticNodes(children, pos, node.pos);
+                children.push(node);
+                pos = node.end;
+            };
+            var processNodes = function (nodes) {
+                if (pos < nodes.pos) {
+                    pos = _this.addSyntheticNodes(children, pos, nodes.pos);
+                }
+                children.push(_this.createSyntaxList(nodes));
+                pos = nodes.end;
+            };
+            // jsDocComments need to be the first children
+            if (this.jsDoc) {
+                for (var _i = 0, _a = this.jsDoc; _i < _a.length; _i++) {
+                    var jsDocComment = _a[_i];
+                    processNode(jsDocComment);
+                }
+            }
+            // For syntactic classifications, all trivia are classcified together, including jsdoc comments.
+            // For that to work, the jsdoc comments should still be the leading trivia of the first child.
+            // Restoring the scanner position ensures that.
+            pos = this.pos;
+            ts.forEachChild(this, processNode, processNodes);
+            if (pos < this.end) {
+                this.addSyntheticNodes(children, pos, this.end);
+            }
+            ts.scanner.setText(undefined);
+            this._children = children;
+        };
+        NodeObject.prototype.getChildCount = function (sourceFile) {
+            if (!this._children)
+                this.createChildren(sourceFile);
+            return this._children.length;
+        };
+        NodeObject.prototype.getChildAt = function (index, sourceFile) {
+            if (!this._children)
+                this.createChildren(sourceFile);
+            return this._children[index];
+        };
+        NodeObject.prototype.getChildren = function (sourceFile) {
+            if (!this._children)
+                this.createChildren(sourceFile);
+            return this._children;
+        };
+        NodeObject.prototype.getFirstToken = function (sourceFile) {
+            var children = this.getChildren(sourceFile);
+            if (!children.length) {
+                return undefined;
+            }
+            var child = ts.find(children, function (kid) { return kid.kind < 267 /* FirstJSDocNode */ || kid.kind > 285 /* LastJSDocNode */; });
+            return child.kind < 143 /* FirstNode */ ?
+                child :
+                child.getFirstToken(sourceFile);
+        };
+        NodeObject.prototype.getLastToken = function (sourceFile) {
+            var children = this.getChildren(sourceFile);
+            var child = ts.lastOrUndefined(children);
+            if (!child) {
+                return undefined;
+            }
+            return child.kind < 143 /* FirstNode */ ? child : child.getLastToken(sourceFile);
+        };
+        NodeObject.prototype.forEachChild = function (cbNode, cbNodeArray) {
+            return ts.forEachChild(this, cbNode, cbNodeArray);
+        };
+        return NodeObject;
+    }());
+    var TokenOrIdentifierObject = /** @class */ (function () {
+        function TokenOrIdentifierObject(pos, end) {
+            // Set properties in same order as NodeObject
+            this.pos = pos;
+            this.end = end;
+            this.flags = 0 /* None */;
+            this.parent = undefined;
+        }
+        TokenOrIdentifierObject.prototype.getSourceFile = function () {
+            return ts.getSourceFileOfNode(this);
+        };
+        TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
+            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
+        };
+        TokenOrIdentifierObject.prototype.getFullStart = function () {
+            return this.pos;
+        };
+        TokenOrIdentifierObject.prototype.getEnd = function () {
+            return this.end;
+        };
+        TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) {
+            return this.getEnd() - this.getStart(sourceFile);
+        };
+        TokenOrIdentifierObject.prototype.getFullWidth = function () {
+            return this.end - this.pos;
+        };
+        TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
+            return this.getStart(sourceFile) - this.pos;
+        };
+        TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) {
+            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
+        };
+        TokenOrIdentifierObject.prototype.getText = function (sourceFile) {
+            return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
+        };
+        TokenOrIdentifierObject.prototype.getChildCount = function () {
+            return 0;
+        };
+        TokenOrIdentifierObject.prototype.getChildAt = function () {
+            return undefined;
+        };
+        TokenOrIdentifierObject.prototype.getChildren = function () {
+            return ts.emptyArray;
+        };
+        TokenOrIdentifierObject.prototype.getFirstToken = function () {
+            return undefined;
+        };
+        TokenOrIdentifierObject.prototype.getLastToken = function () {
+            return undefined;
+        };
+        TokenOrIdentifierObject.prototype.forEachChild = function () {
+            return undefined;
+        };
+        return TokenOrIdentifierObject;
+    }());
+    var SymbolObject = /** @class */ (function () {
+        function SymbolObject(flags, name) {
+            this.flags = flags;
+            this.escapedName = name;
+        }
+        SymbolObject.prototype.getFlags = function () {
+            return this.flags;
+        };
+        Object.defineProperty(SymbolObject.prototype, "name", {
+            get: function () {
+                return ts.symbolName(this);
+            },
+            enumerable: true,
+            configurable: true
+        });
+        SymbolObject.prototype.getEscapedName = function () {
+            return this.escapedName;
+        };
+        SymbolObject.prototype.getName = function () {
+            return this.name;
+        };
+        SymbolObject.prototype.getDeclarations = function () {
+            return this.declarations;
+        };
+        SymbolObject.prototype.getDocumentationComment = function () {
+            if (this.documentationComment === undefined) {
+                this.documentationComment = ts.JsDoc.getJsDocCommentsFromDeclarations(this.declarations);
+            }
+            return this.documentationComment;
+        };
+        SymbolObject.prototype.getJsDocTags = function () {
+            if (this.tags === undefined) {
+                this.tags = ts.JsDoc.getJsDocTagsFromDeclarations(this.declarations);
+            }
+            return this.tags;
+        };
+        return SymbolObject;
+    }());
+    var TokenObject = /** @class */ (function (_super) {
+        __extends(TokenObject, _super);
+        function TokenObject(kind, pos, end) {
+            var _this = _super.call(this, pos, end) || this;
+            _this.kind = kind;
+            return _this;
+        }
+        return TokenObject;
+    }(TokenOrIdentifierObject));
+    var IdentifierObject = /** @class */ (function (_super) {
+        __extends(IdentifierObject, _super);
+        function IdentifierObject(_kind, pos, end) {
+            return _super.call(this, pos, end) || this;
+        }
+        Object.defineProperty(IdentifierObject.prototype, "text", {
+            get: function () {
+                return ts.idText(this);
+            },
+            enumerable: true,
+            configurable: true
+        });
+        return IdentifierObject;
+    }(TokenOrIdentifierObject));
+    IdentifierObject.prototype.kind = 71 /* Identifier */;
+    var TypeObject = /** @class */ (function () {
+        function TypeObject(checker, flags) {
+            this.checker = checker;
+            this.flags = flags;
+        }
+        TypeObject.prototype.getFlags = function () {
+            return this.flags;
+        };
+        TypeObject.prototype.getSymbol = function () {
+            return this.symbol;
+        };
+        TypeObject.prototype.getProperties = function () {
+            return this.checker.getPropertiesOfType(this);
+        };
+        TypeObject.prototype.getProperty = function (propertyName) {
+            return this.checker.getPropertyOfType(this, propertyName);
+        };
+        TypeObject.prototype.getApparentProperties = function () {
+            return this.checker.getAugmentedPropertiesOfType(this);
+        };
+        TypeObject.prototype.getCallSignatures = function () {
+            return this.checker.getSignaturesOfType(this, 0 /* Call */);
+        };
+        TypeObject.prototype.getConstructSignatures = function () {
+            return this.checker.getSignaturesOfType(this, 1 /* Construct */);
+        };
+        TypeObject.prototype.getStringIndexType = function () {
+            return this.checker.getIndexTypeOfType(this, 0 /* String */);
+        };
+        TypeObject.prototype.getNumberIndexType = function () {
+            return this.checker.getIndexTypeOfType(this, 1 /* Number */);
+        };
+        TypeObject.prototype.getBaseTypes = function () {
+            return this.flags & 32768 /* Object */ && this.objectFlags & (1 /* Class */ | 2 /* Interface */)
+                ? this.checker.getBaseTypes(this)
+                : undefined;
+        };
+        TypeObject.prototype.getNonNullableType = function () {
+            return this.checker.getNonNullableType(this);
+        };
+        return TypeObject;
+    }());
+    var SignatureObject = /** @class */ (function () {
+        function SignatureObject(checker) {
+            this.checker = checker;
+        }
+        SignatureObject.prototype.getDeclaration = function () {
+            return this.declaration;
+        };
+        SignatureObject.prototype.getTypeParameters = function () {
+            return this.typeParameters;
+        };
+        SignatureObject.prototype.getParameters = function () {
+            return this.parameters;
+        };
+        SignatureObject.prototype.getReturnType = function () {
+            return this.checker.getReturnTypeOfSignature(this);
+        };
+        SignatureObject.prototype.getDocumentationComment = function () {
+            if (this.documentationComment === undefined) {
+                this.documentationComment = this.declaration ? ts.JsDoc.getJsDocCommentsFromDeclarations([this.declaration]) : [];
+            }
+            return this.documentationComment;
+        };
+        SignatureObject.prototype.getJsDocTags = function () {
+            if (this.jsDocTags === undefined) {
+                this.jsDocTags = this.declaration ? ts.JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
+            }
+            return this.jsDocTags;
+        };
+        return SignatureObject;
+    }());
+    var SourceFileObject = /** @class */ (function (_super) {
+        __extends(SourceFileObject, _super);
+        function SourceFileObject(kind, pos, end) {
+            return _super.call(this, kind, pos, end) || this;
+        }
+        SourceFileObject.prototype.update = function (newText, textChangeRange) {
+            return ts.updateSourceFile(this, newText, textChangeRange);
+        };
+        SourceFileObject.prototype.getLineAndCharacterOfPosition = function (position) {
+            return ts.getLineAndCharacterOfPosition(this, position);
+        };
+        SourceFileObject.prototype.getLineStarts = function () {
+            return ts.getLineStarts(this);
+        };
+        SourceFileObject.prototype.getPositionOfLineAndCharacter = function (line, character) {
+            return ts.getPositionOfLineAndCharacter(this, line, character);
+        };
+        SourceFileObject.prototype.getLineEndOfPosition = function (pos) {
+            var line = this.getLineAndCharacterOfPosition(pos).line;
+            var lineStarts = this.getLineStarts();
+            var lastCharPos;
+            if (line + 1 >= lineStarts.length) {
+                lastCharPos = this.getEnd();
+            }
+            if (!lastCharPos) {
+                lastCharPos = lineStarts[line + 1] - 1;
+            }
+            var fullText = this.getFullText();
+            // if the new line is "\r\n", we should return the last non-new-line-character position
+            return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos;
+        };
+        SourceFileObject.prototype.getNamedDeclarations = function () {
+            if (!this.namedDeclarations) {
+                this.namedDeclarations = this.computeNamedDeclarations();
+            }
+            return this.namedDeclarations;
+        };
+        SourceFileObject.prototype.computeNamedDeclarations = function () {
+            var result = ts.createMultiMap();
+            ts.forEachChild(this, visit);
+            return result;
+            function addDeclaration(declaration) {
+                var name = getDeclarationName(declaration);
+                if (name) {
+                    result.add(name, declaration);
+                }
+            }
+            function getDeclarations(name) {
+                var declarations = result.get(name);
+                if (!declarations) {
+                    result.set(name, declarations = []);
+                }
+                return declarations;
+            }
+            function getDeclarationName(declaration) {
+                var name = ts.getNameOfDeclaration(declaration);
+                if (name) {
+                    var result_9 = ts.getTextOfIdentifierOrLiteral(name);
+                    if (result_9 !== undefined) {
+                        return result_9;
+                    }
+                    if (name.kind === 144 /* ComputedPropertyName */) {
+                        var expr = name.expression;
+                        if (expr.kind === 179 /* PropertyAccessExpression */) {
+                            return expr.name.text;
+                        }
+                        return ts.getTextOfIdentifierOrLiteral(expr);
+                    }
+                }
+                return undefined;
+            }
+            function visit(node) {
+                switch (node.kind) {
+                    case 228 /* FunctionDeclaration */:
+                    case 186 /* FunctionExpression */:
+                    case 151 /* MethodDeclaration */:
+                    case 150 /* MethodSignature */:
+                        var functionDeclaration = node;
+                        var declarationName = getDeclarationName(functionDeclaration);
+                        if (declarationName) {
+                            var declarations = getDeclarations(declarationName);
+                            var lastDeclaration = ts.lastOrUndefined(declarations);
+                            // Check whether this declaration belongs to an "overload group".
+                            if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) {
+                                // Overwrite the last declaration if it was an overload
+                                // and this one is an implementation.
+                                if (functionDeclaration.body && !lastDeclaration.body) {
+                                    declarations[declarations.length - 1] = functionDeclaration;
+                                }
+                            }
+                            else {
+                                declarations.push(functionDeclaration);
+                            }
+                        }
+                        ts.forEachChild(node, visit);
+                        break;
+                    case 229 /* ClassDeclaration */:
+                    case 199 /* ClassExpression */:
+                    case 230 /* InterfaceDeclaration */:
+                    case 231 /* TypeAliasDeclaration */:
+                    case 232 /* EnumDeclaration */:
+                    case 233 /* ModuleDeclaration */:
+                    case 237 /* ImportEqualsDeclaration */:
+                    case 246 /* ExportSpecifier */:
+                    case 242 /* ImportSpecifier */:
+                    case 239 /* ImportClause */:
+                    case 240 /* NamespaceImport */:
+                    case 153 /* GetAccessor */:
+                    case 154 /* SetAccessor */:
+                    case 163 /* TypeLiteral */:
+                        addDeclaration(node);
+                        ts.forEachChild(node, visit);
+                        break;
+                    case 146 /* Parameter */:
+                        // Only consider parameter properties
+                        if (!ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
+                            break;
+                        }
+                    // falls through
+                    case 226 /* VariableDeclaration */:
+                    case 176 /* BindingElement */: {
+                        var decl = node;
+                        if (ts.isBindingPattern(decl.name)) {
+                            ts.forEachChild(decl.name, visit);
+                            break;
+                        }
+                        if (decl.initializer) {
+                            visit(decl.initializer);
+                        }
+                    }
+                    // falls through
+                    case 264 /* EnumMember */:
+                    case 149 /* PropertyDeclaration */:
+                    case 148 /* PropertySignature */:
+                        addDeclaration(node);
+                        break;
+                    case 244 /* ExportDeclaration */:
+                        // Handle named exports case e.g.:
+                        //    export {a, b as B} from "mod";
+                        if (node.exportClause) {
+                            ts.forEach(node.exportClause.elements, visit);
+                        }
+                        break;
+                    case 238 /* ImportDeclaration */:
+                        var importClause = node.importClause;
+                        if (importClause) {
+                            // Handle default import case e.g.:
+                            //    import d from "mod";
+                            if (importClause.name) {
+                                addDeclaration(importClause);
+                            }
+                            // Handle named bindings in imports e.g.:
+                            //    import * as NS from "mod";
+                            //    import {a, b as B} from "mod";
+                            if (importClause.namedBindings) {
+                                if (importClause.namedBindings.kind === 240 /* NamespaceImport */) {
+                                    addDeclaration(importClause.namedBindings);
+                                }
+                                else {
+                                    ts.forEach(importClause.namedBindings.elements, visit);
+                                }
+                            }
+                        }
+                        break;
+                    case 194 /* BinaryExpression */:
+                        if (ts.getSpecialPropertyAssignmentKind(node) !== 0 /* None */) {
+                            addDeclaration(node);
+                        }
+                    // falls through
+                    default:
+                        ts.forEachChild(node, visit);
+                }
+            }
+        };
+        return SourceFileObject;
+    }(NodeObject));
+    var SourceMapSourceObject = /** @class */ (function () {
+        function SourceMapSourceObject(fileName, text, skipTrivia) {
+            this.fileName = fileName;
+            this.text = text;
+            this.skipTrivia = skipTrivia;
+        }
+        SourceMapSourceObject.prototype.getLineAndCharacterOfPosition = function (pos) {
+            return ts.getLineAndCharacterOfPosition(this, pos);
+        };
+        return SourceMapSourceObject;
+    }());
+    function getServicesObjectAllocator() {
+        return {
+            getNodeConstructor: function () { return NodeObject; },
+            getTokenConstructor: function () { return TokenObject; },
+            getIdentifierConstructor: function () { return IdentifierObject; },
+            getSourceFileConstructor: function () { return SourceFileObject; },
+            getSymbolConstructor: function () { return SymbolObject; },
+            getTypeConstructor: function () { return TypeObject; },
+            getSignatureConstructor: function () { return SignatureObject; },
+            getSourceMapSourceConstructor: function () { return SourceMapSourceObject; },
+        };
+    }
+    function toEditorSettings(optionsAsMap) {
+        var allPropertiesAreCamelCased = true;
+        for (var key in optionsAsMap) {
+            if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) {
+                allPropertiesAreCamelCased = false;
+                break;
+            }
+        }
+        if (allPropertiesAreCamelCased) {
+            return optionsAsMap;
+        }
+        var settings = {};
+        for (var key in optionsAsMap) {
+            if (ts.hasProperty(optionsAsMap, key)) {
+                var newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1);
+                settings[newKey] = optionsAsMap[key];
+            }
+        }
+        return settings;
+    }
+    ts.toEditorSettings = toEditorSettings;
+    function isCamelCase(s) {
+        return !s.length || s.charAt(0) === s.charAt(0).toLowerCase();
+    }
+    function displayPartsToString(displayParts) {
+        if (displayParts) {
+            return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
+        }
+        return "";
+    }
+    ts.displayPartsToString = displayPartsToString;
+    function getDefaultCompilerOptions() {
+        // Always default to "ScriptTarget.ES5" for the language service
+        return {
+            target: 1 /* ES5 */,
+            jsx: 1 /* Preserve */
+        };
+    }
+    ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
+    function getSupportedCodeFixes() {
+        return ts.codefix.getSupportedErrorCodes();
+    }
+    ts.getSupportedCodeFixes = getSupportedCodeFixes;
+    // Cache host information about script Should be refreshed
+    // at each language service public entry point, since we don't know when
+    // the set of scripts handled by the host changes.
+    var HostCache = /** @class */ (function () {
+        function HostCache(host, getCanonicalFileName) {
+            this.host = host;
+            // script id => script index
+            this.currentDirectory = host.getCurrentDirectory();
+            this.fileNameToEntry = ts.createMap();
+            // Initialize the list with the root file names
+            var rootFileNames = host.getScriptFileNames();
+            for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) {
+                var fileName = rootFileNames_1[_i];
+                this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName));
+            }
+            // store the compilation settings
+            this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
+        }
+        HostCache.prototype.compilationSettings = function () {
+            return this._compilationSettings;
+        };
+        HostCache.prototype.createEntry = function (fileName, path) {
+            var entry;
+            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
+            if (scriptSnapshot) {
+                entry = {
+                    hostFileName: fileName,
+                    version: this.host.getScriptVersion(fileName),
+                    scriptSnapshot: scriptSnapshot,
+                    scriptKind: ts.getScriptKind(fileName, this.host)
+                };
+            }
+            else {
+                entry = fileName;
+            }
+            this.fileNameToEntry.set(path, entry);
+            return entry;
+        };
+        HostCache.prototype.getEntryByPath = function (path) {
+            return this.fileNameToEntry.get(path);
+        };
+        HostCache.prototype.getHostFileInformation = function (path) {
+            var entry = this.fileNameToEntry.get(path);
+            return !ts.isString(entry) ? entry : undefined;
+        };
+        HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) {
+            var info = this.getEntryByPath(path) || this.createEntry(fileName, path);
+            return ts.isString(info) ? undefined : info;
+        };
+        HostCache.prototype.getRootFileNames = function () {
+            return ts.arrayFrom(this.fileNameToEntry.values(), function (entry) {
+                return ts.isString(entry) ? entry : entry.hostFileName;
+            });
+        };
+        HostCache.prototype.getVersion = function (path) {
+            var file = this.getHostFileInformation(path);
+            return file && file.version;
+        };
+        HostCache.prototype.getScriptSnapshot = function (path) {
+            var file = this.getHostFileInformation(path);
+            return file && file.scriptSnapshot;
+        };
+        return HostCache;
+    }());
+    var SyntaxTreeCache = /** @class */ (function () {
+        function SyntaxTreeCache(host) {
+            this.host = host;
+        }
+        SyntaxTreeCache.prototype.getCurrentSourceFile = function (fileName) {
+            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
+            if (!scriptSnapshot) {
+                // The host does not know about this file.
+                throw new Error("Could not find file: '" + fileName + "'.");
+            }
+            var scriptKind = ts.getScriptKind(fileName, this.host);
+            var version = this.host.getScriptVersion(fileName);
+            var sourceFile;
+            if (this.currentFileName !== fileName) {
+                // This is a new file, just parse it
+                sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, 5 /* Latest */, version, /*setNodeParents*/ true, scriptKind);
+            }
+            else if (this.currentFileVersion !== version) {
+                // This is the same file, just a newer version. Incrementally parse the file.
+                var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
+                sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
+            }
+            if (sourceFile) {
+                // All done, ensure state is up to date
+                this.currentFileVersion = version;
+                this.currentFileName = fileName;
+                this.currentFileScriptSnapshot = scriptSnapshot;
+                this.currentSourceFile = sourceFile;
+            }
+            return this.currentSourceFile;
+        };
+        return SyntaxTreeCache;
+    }());
+    function setSourceFileFields(sourceFile, scriptSnapshot, version) {
+        sourceFile.version = version;
+        sourceFile.scriptSnapshot = scriptSnapshot;
+    }
+    function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind) {
+        var text = scriptSnapshot.getText(0, scriptSnapshot.getLength());
+        var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind);
+        setSourceFileFields(sourceFile, scriptSnapshot, version);
+        return sourceFile;
+    }
+    ts.createLanguageServiceSourceFile = createLanguageServiceSourceFile;
+    ts.disableIncrementalParsing = false;
+    function updateLanguageServiceSourceFile(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks) {
+        // If we were given a text change range, and our version or open-ness changed, then
+        // incrementally parse this file.
+        if (textChangeRange) {
+            if (version !== sourceFile.version) {
+                // Once incremental parsing is ready, then just call into this function.
+                if (!ts.disableIncrementalParsing) {
+                    var newText = void 0;
+                    // grab the fragment from the beginning of the original text to the beginning of the span
+                    var prefix = textChangeRange.span.start !== 0
+                        ? sourceFile.text.substr(0, textChangeRange.span.start)
+                        : "";
+                    // grab the fragment from the end of the span till the end of the original text
+                    var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length
+                        ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span))
+                        : "";
+                    if (textChangeRange.newLength === 0) {
+                        // edit was a deletion - just combine prefix and suffix
+                        newText = prefix && suffix ? prefix + suffix : prefix || suffix;
+                    }
+                    else {
+                        // it was actual edit, fetch the fragment of new text that correspond to new span
+                        var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength);
+                        // combine prefix, changed text and suffix
+                        newText = prefix && suffix
+                            ? prefix + changedText + suffix
+                            : prefix
+                                ? (prefix + changedText)
+                                : (changedText + suffix);
+                    }
+                    var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
+                    setSourceFileFields(newSourceFile, scriptSnapshot, version);
+                    // after incremental parsing nameTable might not be up-to-date
+                    // drop it so it can be lazily recreated later
+                    newSourceFile.nameTable = undefined;
+                    // dispose all resources held by old script snapshot
+                    if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) {
+                        if (sourceFile.scriptSnapshot.dispose) {
+                            sourceFile.scriptSnapshot.dispose();
+                        }
+                        sourceFile.scriptSnapshot = undefined;
+                    }
+                    return newSourceFile;
+                }
+            }
+        }
+        // Otherwise, just create a new source file.
+        return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind);
+    }
+    ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile;
+    var CancellationTokenObject = /** @class */ (function () {
+        function CancellationTokenObject(cancellationToken) {
+            this.cancellationToken = cancellationToken;
+        }
+        CancellationTokenObject.prototype.isCancellationRequested = function () {
+            return this.cancellationToken && this.cancellationToken.isCancellationRequested();
+        };
+        CancellationTokenObject.prototype.throwIfCancellationRequested = function () {
+            if (this.isCancellationRequested()) {
+                throw new ts.OperationCanceledException();
+            }
+        };
+        return CancellationTokenObject;
+    }());
+    /* @internal */
+    /** A cancellation that throttles calls to the host */
+    var ThrottledCancellationToken = /** @class */ (function () {
+        function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) {
+            if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; }
+            this.hostCancellationToken = hostCancellationToken;
+            this.throttleWaitMilliseconds = throttleWaitMilliseconds;
+            // Store when we last tried to cancel.  Checking cancellation can be expensive (as we have
+            // to marshall over to the host layer).  So we only bother actually checking once enough
+            // time has passed.
+            this.lastCancellationCheckTime = 0;
+        }
+        ThrottledCancellationToken.prototype.isCancellationRequested = function () {
+            var time = ts.timestamp();
+            var duration = Math.abs(time - this.lastCancellationCheckTime);
+            if (duration >= this.throttleWaitMilliseconds) {
+                // Check no more than once every throttle wait milliseconds
+                this.lastCancellationCheckTime = time;
+                return this.hostCancellationToken.isCancellationRequested();
+            }
+            return false;
+        };
+        ThrottledCancellationToken.prototype.throwIfCancellationRequested = function () {
+            if (this.isCancellationRequested()) {
+                throw new ts.OperationCanceledException();
+            }
+        };
+        return ThrottledCancellationToken;
+    }());
+    ts.ThrottledCancellationToken = ThrottledCancellationToken;
+    function createLanguageService(host, documentRegistry) {
+        if (documentRegistry === void 0) { documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); }
+        var syntaxTreeCache = new SyntaxTreeCache(host);
+        ruleProvider = ruleProvider || new ts.formatting.RulesProvider();
+        var program;
+        var lastProjectVersion;
+        var lastTypesRootVersion = 0;
+        var useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames();
+        var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
+        var currentDirectory = host.getCurrentDirectory();
+        // Check if the localized messages json is set, otherwise query the host for it
+        if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) {
+            ts.localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages();
+        }
+        function log(message) {
+            if (host.log) {
+                host.log(message);
+            }
+        }
+        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitivefileNames);
+        function getValidSourceFile(fileName) {
+            var sourceFile = program.getSourceFile(fileName);
+            if (!sourceFile) {
+                throw new Error("Could not find file: '" + fileName + "'.");
+            }
+            return sourceFile;
+        }
+        function getRuleProvider(options) {
+            ruleProvider.ensureUpToDate(options);
+            return ruleProvider;
+        }
+        function synchronizeHostData() {
+            // perform fast check if host supports it
+            if (host.getProjectVersion) {
+                var hostProjectVersion = host.getProjectVersion();
+                if (hostProjectVersion) {
+                    if (lastProjectVersion === hostProjectVersion && !host.hasChangedAutomaticTypeDirectiveNames) {
+                        return;
+                    }
+                    lastProjectVersion = hostProjectVersion;
+                }
+            }
+            var typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0;
+            if (lastTypesRootVersion !== typeRootsVersion) {
+                log("TypeRoots version has changed; provide new program");
+                program = undefined;
+                lastTypesRootVersion = typeRootsVersion;
+            }
+            // Get a fresh cache of the host information
+            var hostCache = new HostCache(host, getCanonicalFileName);
+            var rootFileNames = hostCache.getRootFileNames();
+            var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
+            // If the program is already up-to-date, we can reuse it
+            if (ts.isProgramUptoDate(program, rootFileNames, hostCache.compilationSettings(), function (path) { return hostCache.getVersion(path); }, fileExists, hasInvalidatedResolution, host.hasChangedAutomaticTypeDirectiveNames)) {
+                return;
+            }
+            // IMPORTANT - It is critical from this moment onward that we do not check
+            // cancellation tokens.  We are about to mutate source files from a previous program
+            // instance.  If we cancel midway through, we may end up in an inconsistent state where
+            // the program points to old source files that have been invalidated because of
+            // incremental parsing.
+            var newSettings = hostCache.compilationSettings();
+            // Now create a new compiler
+            var compilerHost = {
+                getSourceFile: getOrCreateSourceFile,
+                getSourceFileByPath: getOrCreateSourceFileByPath,
+                getCancellationToken: function () { return cancellationToken; },
+                getCanonicalFileName: getCanonicalFileName,
+                useCaseSensitiveFileNames: function () { return useCaseSensitivefileNames; },
+                getNewLine: function () { return ts.getNewLineCharacter(newSettings, { newLine: ts.getNewLineOrDefaultFromHost(host) }); },
+                getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
+                writeFile: ts.noop,
+                getCurrentDirectory: function () { return currentDirectory; },
+                fileExists: fileExists,
+                readFile: function (fileName) {
+                    // stub missing host functionality
+                    var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+                    var entry = hostCache.getEntryByPath(path);
+                    if (entry) {
+                        return ts.isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength());
+                    }
+                    return host.readFile && host.readFile(fileName);
+                },
+                directoryExists: function (directoryName) {
+                    return ts.directoryProbablyExists(directoryName, host);
+                },
+                getDirectories: function (path) {
+                    return host.getDirectories ? host.getDirectories(path) : [];
+                },
+                onReleaseOldSourceFile: onReleaseOldSourceFile,
+                hasInvalidatedResolution: hasInvalidatedResolution,
+                hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames
+            };
+            if (host.trace) {
+                compilerHost.trace = function (message) { return host.trace(message); };
+            }
+            if (host.resolveModuleNames) {
+                compilerHost.resolveModuleNames = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(moduleNames, containingFile, reusedNames); };
+            }
+            if (host.resolveTypeReferenceDirectives) {
+                compilerHost.resolveTypeReferenceDirectives = function (typeReferenceDirectiveNames, containingFile) {
+                    return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile);
+                };
+            }
+            var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
+            program = ts.createProgram(rootFileNames, newSettings, compilerHost, program);
+            // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point.
+            // It needs to be cleared to allow all collected snapshots to be released
+            hostCache = undefined;
+            // Make sure all the nodes in the program are both bound, and have their parent
+            // pointers set property.
+            program.getTypeChecker();
+            return;
+            function fileExists(fileName) {
+                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+                var entry = hostCache.getEntryByPath(path);
+                return entry ?
+                    !ts.isString(entry) :
+                    (host.fileExists && host.fileExists(fileName));
+            }
+            // Release any files we have acquired in the old program but are
+            // not part of the new program.
+            function onReleaseOldSourceFile(oldSourceFile, oldOptions) {
+                var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions);
+                documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey);
+            }
+            function getOrCreateSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
+                return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile);
+            }
+            function getOrCreateSourceFileByPath(fileName, path, _languageVersion, _onError, shouldCreateNewSourceFile) {
+                ts.Debug.assert(hostCache !== undefined);
+                // The program is asking for this file, check first if the host can locate it.
+                // If the host can not locate the file, then it does not exist. return undefined
+                // to the program to allow reporting of errors for missing files.
+                var hostFileInformation = hostCache.getOrCreateEntryByPath(fileName, path);
+                if (!hostFileInformation) {
+                    return undefined;
+                }
+                // Check if the language version has changed since we last created a program; if they are the same,
+                // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile
+                // can not be reused. we have to dump all syntax trees and create new ones.
+                if (!shouldCreateNewSourceFile) {
+                    // Check if the old program had this file already
+                    var oldSourceFile = program && program.getSourceFileByPath(path);
+                    if (oldSourceFile) {
+                        // We already had a source file for this file name.  Go to the registry to
+                        // ensure that we get the right up to date version of it.  We need this to
+                        // address the following race-condition.  Specifically, say we have the following:
+                        //
+                        //      LS1
+                        //          \
+                        //           DocumentRegistry
+                        //          /
+                        //      LS2
+                        //
+                        // Each LS has a reference to file 'foo.ts' at version 1.  LS2 then updates
+                        // it's version of 'foo.ts' to version 2.  This will cause LS2 and the
+                        // DocumentRegistry to have version 2 of the document.  HOwever, LS1 will
+                        // have version 1.  And *importantly* this source file will be *corrupt*.
+                        // The act of creating version 2 of the file irrevocably damages the version
+                        // 1 file.
+                        //
+                        // So, later when we call into LS1, we need to make sure that it doesn't use
+                        // it's source file any more, and instead defers to DocumentRegistry to get
+                        // either version 1, version 2 (or some other version) depending on what the
+                        // host says should be used.
+                        // We do not support the scenario where a host can modify a registered
+                        // file's script kind, i.e. in one project some file is treated as ".ts"
+                        // and in another as ".js"
+                        ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path);
+                        return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
+                    }
+                    // We didn't already have the file.  Fall through and acquire it from the registry.
+                }
+                // Could not find this file in the old program, create a new SourceFile for it.
+                return documentRegistry.acquireDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
+            }
+        }
+        function getProgram() {
+            synchronizeHostData();
+            return program;
+        }
+        function cleanupSemanticCache() {
+            program = undefined;
+        }
+        function dispose() {
+            if (program) {
+                ts.forEach(program.getSourceFiles(), function (f) {
+                    return documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions());
+                });
+                program = undefined;
+            }
+            host = undefined;
+        }
+        /// Diagnostics
+        function getSyntacticDiagnostics(fileName) {
+            synchronizeHostData();
+            return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
+        }
+        /**
+         * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors
+         * If '-d' enabled, report both semantic and emitter errors
+         */
+        function getSemanticDiagnostics(fileName) {
+            synchronizeHostData();
+            var targetSourceFile = getValidSourceFile(fileName);
+            // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
+            // Therefore only get diagnostics for given file.
+            var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
+            if (!program.getCompilerOptions().declaration) {
+                return semanticDiagnostics.slice();
+            }
+            // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
+            var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
+            return semanticDiagnostics.concat(declarationDiagnostics);
+        }
+        function getCompilerOptionsDiagnostics() {
+            synchronizeHostData();
+            return program.getOptionsDiagnostics(cancellationToken).concat(program.getGlobalDiagnostics(cancellationToken));
+        }
+        function getCompletionsAtPosition(fileName, position) {
+            synchronizeHostData();
+            return ts.Completions.getCompletionsAtPosition(host, program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, program.getSourceFiles());
+        }
+        function getCompletionEntryDetails(fileName, position, name, formattingOptions, source) {
+            synchronizeHostData();
+            var ruleProvider = formattingOptions ? getRuleProvider(formattingOptions) : undefined;
+            return ts.Completions.getCompletionEntryDetails(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles(), host, ruleProvider);
+        }
+        function getCompletionEntrySymbol(fileName, position, name, source) {
+            synchronizeHostData();
+            return ts.Completions.getCompletionEntrySymbol(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles());
+        }
+        function getQuickInfoAtPosition(fileName, position) {
+            synchronizeHostData();
+            var sourceFile = getValidSourceFile(fileName);
+            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
+            if (node === sourceFile) {
+                return undefined;
+            }
+            if (ts.isLabelName(node)) {
+                return undefined;
+            }
+            var typeChecker = program.getTypeChecker();
+            var symbol = getSymbolAtLocationForQuickInfo(node, typeChecker);
+            if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
+                // Try getting just type at this position and show
+                switch (node.kind) {
+                    case 71 /* Identifier */:
+                    case 179 /* PropertyAccessExpression */:
+                    case 143 /* QualifiedName */:
+                    case 99 /* ThisKeyword */:
+                    case 169 /* ThisType */:
+                    case 97 /* SuperKeyword */:
+                        // For the identifiers/this/super etc get the type at position
+                        var type = typeChecker.getTypeAtLocation(node);
+                        if (type) {
+                            return {
+                                kind: "" /* unknown */,
+                                kindModifiers: "" /* none */,
+                                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
+                                displayParts: ts.typeToDisplayParts(typeChecker, type, ts.getContainerNode(node)),
+                                documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined,
+                                tags: type.symbol ? type.symbol.getJsDocTags() : undefined
+                            };
+                        }
+                }
+                return undefined;
+            }
+            var displayPartsDocumentationsAndKind = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(node), node);
+            return {
+                kind: displayPartsDocumentationsAndKind.symbolKind,
+                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
+                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
+                displayParts: displayPartsDocumentationsAndKind.displayParts,
+                documentation: displayPartsDocumentationsAndKind.documentation,
+                tags: displayPartsDocumentationsAndKind.tags
+            };
+        }
+        function getSymbolAtLocationForQuickInfo(node, checker) {
+            if ((ts.isIdentifier(node) || ts.isStringLiteral(node))
+                && ts.isPropertyAssignment(node.parent)
+                && node.parent.name === node) {
+                var type = checker.getContextualType(node.parent.parent);
+                if (type) {
+                    var property = checker.getPropertyOfType(type, ts.getTextOfIdentifierOrLiteral(node));
+                    if (property) {
+                        return property;
+                    }
+                }
+            }
+            return checker.getSymbolAtLocation(node);
+        }
+        /// Goto definition
+        function getDefinitionAtPosition(fileName, position) {
+            synchronizeHostData();
+            return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position);
+        }
+        function getTypeDefinitionAtPosition(fileName, position) {
+            synchronizeHostData();
+            return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position);
+        }
+        /// Goto implementation
+        function getImplementationAtPosition(fileName, position) {
+            synchronizeHostData();
+            return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
+        }
+        /// References and Occurrences
+        function getOccurrencesAtPosition(fileName, position) {
+            var results = getOccurrencesAtPositionCore(fileName, position);
+            if (results) {
+                var sourceFile_1 = getCanonicalFileName(ts.normalizeSlashes(fileName));
+                // Get occurrences only supports reporting occurrences for the file queried.  So
+                // filter down to that list.
+                results = ts.filter(results, function (r) { return getCanonicalFileName(ts.normalizeSlashes(r.fileName)) === sourceFile_1; });
+            }
+            return results;
+        }
+        function getDocumentHighlights(fileName, position, filesToSearch) {
+            synchronizeHostData();
+            var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); });
+            var sourceFile = getValidSourceFile(fileName);
+            return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch);
+        }
+        function getOccurrencesAtPositionCore(fileName, position) {
+            return convertDocumentHighlights(getDocumentHighlights(fileName, position, [fileName]));
+            function convertDocumentHighlights(documentHighlights) {
+                if (!documentHighlights) {
+                    return undefined;
+                }
+                var result = [];
+                for (var _i = 0, documentHighlights_1 = documentHighlights; _i < documentHighlights_1.length; _i++) {
+                    var entry = documentHighlights_1[_i];
+                    for (var _a = 0, _b = entry.highlightSpans; _a < _b.length; _a++) {
+                        var highlightSpan = _b[_a];
+                        result.push({
+                            fileName: entry.fileName,
+                            textSpan: highlightSpan.textSpan,
+                            isWriteAccess: highlightSpan.kind === "writtenReference" /* writtenReference */,
+                            isDefinition: false,
+                            isInString: highlightSpan.isInString,
+                        });
+                    }
+                }
+                return result;
+            }
+        }
+        function findRenameLocations(fileName, position, findInStrings, findInComments) {
+            return getReferences(fileName, position, { findInStrings: findInStrings, findInComments: findInComments, isForRename: true });
+        }
+        function getReferencesAtPosition(fileName, position) {
+            return getReferences(fileName, position);
+        }
+        function getReferences(fileName, position, options) {
+            synchronizeHostData();
+            // Exclude default library when renaming as commonly user don't want to change that file.
+            var sourceFiles = [];
+            if (options && options.isForRename) {
+                for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
+                    var sourceFile = _a[_i];
+                    if (!program.isSourceFileDefaultLibrary(sourceFile)) {
+                        sourceFiles.push(sourceFile);
+                    }
+                }
+            }
+            else {
+                sourceFiles = program.getSourceFiles().slice();
+            }
+            return ts.FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, getValidSourceFile(fileName), position, options);
+        }
+        function findReferences(fileName, position) {
+            synchronizeHostData();
+            return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
+        }
+        /// NavigateTo
+        function getNavigateToItems(searchValue, maxResultCount, fileName, excludeDtsFiles) {
+            synchronizeHostData();
+            var sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles();
+            return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles);
+        }
+        function getEmitOutput(fileName, emitOnlyDtsFiles) {
+            synchronizeHostData();
+            var sourceFile = getValidSourceFile(fileName);
+            var customTransformers = host.getCustomTransformers && host.getCustomTransformers();
+            return ts.getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers);
+        }
+        // Signature help
+        /**
+         * This is a semantic operation.
+         */
+        function getSignatureHelpItems(fileName, position) {
+            synchronizeHostData();
+            var sourceFile = getValidSourceFile(fileName);
+            return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken);
+        }
+        /// Syntactic features
+        function getNonBoundSourceFile(fileName) {
+            return syntaxTreeCache.getCurrentSourceFile(fileName);
+        }
+        function getSourceFile(fileName) {
+            return getNonBoundSourceFile(fileName);
+        }
+        function getNameOrDottedNameSpan(fileName, startPos, _endPos) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            // Get node at the location
+            var node = ts.getTouchingPropertyName(sourceFile, startPos, /*includeJsDocComment*/ false);
+            if (node === sourceFile) {
+                return;
+            }
+            switch (node.kind) {
+                case 179 /* PropertyAccessExpression */:
+                case 143 /* QualifiedName */:
+                case 9 /* StringLiteral */:
+                case 86 /* FalseKeyword */:
+                case 101 /* TrueKeyword */:
+                case 95 /* NullKeyword */:
+                case 97 /* SuperKeyword */:
+                case 99 /* ThisKeyword */:
+                case 169 /* ThisType */:
+                case 71 /* Identifier */:
+                    break;
+                // Cant create the text span
+                default:
+                    return;
+            }
+            var nodeForStartPos = node;
+            while (true) {
+                if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) {
+                    // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
+                    nodeForStartPos = nodeForStartPos.parent;
+                }
+                else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) {
+                    // If this is name of a module declarations, check if this is right side of dotted module name
+                    // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
+                    // Then this name is name from dotted module
+                    if (nodeForStartPos.parent.parent.kind === 233 /* ModuleDeclaration */ &&
+                        nodeForStartPos.parent.parent.body === nodeForStartPos.parent) {
+                        // Use parent module declarations name for start pos
+                        nodeForStartPos = nodeForStartPos.parent.parent.name;
+                    }
+                    else {
+                        // We have to use this name for start pos
+                        break;
+                    }
+                }
+                else {
+                    // Is not a member expression so we have found the node for start pos
+                    break;
+                }
+            }
+            return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd());
+        }
+        function getBreakpointStatementAtPosition(fileName, position) {
+            // doesn't use compiler - no need to synchronize with host
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
+        }
+        function getNavigationBarItems(fileName) {
+            return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
+        }
+        function getNavigationTree(fileName) {
+            return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
+        }
+        function isTsOrTsxFile(fileName) {
+            var kind = ts.getScriptKind(fileName, host);
+            return kind === 3 /* TS */ || kind === 4 /* TSX */;
+        }
+        function getSemanticClassifications(fileName, span) {
+            if (!isTsOrTsxFile(fileName)) {
+                // do not run semantic classification on non-ts-or-tsx files
+                return [];
+            }
+            synchronizeHostData();
+            return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
+        }
+        function getEncodedSemanticClassifications(fileName, span) {
+            if (!isTsOrTsxFile(fileName)) {
+                // do not run semantic classification on non-ts-or-tsx files
+                return { spans: [], endOfLineState: 0 /* None */ };
+            }
+            synchronizeHostData();
+            return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
+        }
+        function getSyntacticClassifications(fileName, span) {
+            // doesn't use compiler - no need to synchronize with host
+            return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
+        }
+        function getEncodedSyntacticClassifications(fileName, span) {
+            // doesn't use compiler - no need to synchronize with host
+            return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
+        }
+        function getOutliningSpans(fileName) {
+            // doesn't use compiler - no need to synchronize with host
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
+        }
+        function getBraceMatchingAtPosition(fileName, position) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            var result = [];
+            var token = ts.getTouchingToken(sourceFile, position, /*includeJsDocComment*/ false);
+            if (token.getStart(sourceFile) === position) {
+                var matchKind = getMatchingTokenKind(token);
+                // Ensure that there is a corresponding token to match ours.
+                if (matchKind) {
+                    var parentElement = token.parent;
+                    var childNodes = parentElement.getChildren(sourceFile);
+                    for (var _i = 0, childNodes_1 = childNodes; _i < childNodes_1.length; _i++) {
+                        var current = childNodes_1[_i];
+                        if (current.kind === matchKind) {
+                            var range1 = ts.createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile));
+                            var range2 = ts.createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile));
+                            // We want to order the braces when we return the result.
+                            if (range1.start < range2.start) {
+                                result.push(range1, range2);
+                            }
+                            else {
+                                result.push(range2, range1);
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+            return result;
+            function getMatchingTokenKind(token) {
+                switch (token.kind) {
+                    case 17 /* OpenBraceToken */: return 18 /* CloseBraceToken */;
+                    case 19 /* OpenParenToken */: return 20 /* CloseParenToken */;
+                    case 21 /* OpenBracketToken */: return 22 /* CloseBracketToken */;
+                    case 27 /* LessThanToken */: return 29 /* GreaterThanToken */;
+                    case 18 /* CloseBraceToken */: return 17 /* OpenBraceToken */;
+                    case 20 /* CloseParenToken */: return 19 /* OpenParenToken */;
+                    case 22 /* CloseBracketToken */: return 21 /* OpenBracketToken */;
+                    case 29 /* GreaterThanToken */: return 27 /* LessThanToken */;
+                }
+                return undefined;
+            }
+        }
+        function getIndentationAtPosition(fileName, position, editorOptions) {
+            var start = ts.timestamp();
+            var settings = toEditorSettings(editorOptions);
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start));
+            start = ts.timestamp();
+            var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings);
+            log("getIndentationAtPosition: computeIndentation  : " + (ts.timestamp() - start));
+            return result;
+        }
+        function getFormattingEditsForRange(fileName, start, end, options) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            var settings = toEditorSettings(options);
+            return ts.formatting.formatSelection(start, end, sourceFile, getRuleProvider(settings), settings);
+        }
+        function getFormattingEditsForDocument(fileName, options) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            var settings = toEditorSettings(options);
+            return ts.formatting.formatDocument(sourceFile, getRuleProvider(settings), settings);
+        }
+        function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            var settings = toEditorSettings(options);
+            if (!ts.isInComment(sourceFile, position)) {
+                if (key === "{") {
+                    return ts.formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings);
+                }
+                else if (key === "}") {
+                    return ts.formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings);
+                }
+                else if (key === ";") {
+                    return ts.formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings);
+                }
+                else if (key === "\n") {
+                    return ts.formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings);
+                }
+            }
+            return [];
+        }
+        function getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions) {
+            synchronizeHostData();
+            var sourceFile = getValidSourceFile(fileName);
+            var span = ts.createTextSpanFromBounds(start, end);
+            var newLineCharacter = ts.getNewLineOrDefaultFromHost(host);
+            var rulesProvider = getRuleProvider(formatOptions);
+            return ts.flatMap(ts.deduplicate(errorCodes), function (errorCode) {
+                cancellationToken.throwIfCancellationRequested();
+                return ts.codefix.getFixes({ errorCode: errorCode, sourceFile: sourceFile, span: span, program: program, newLineCharacter: newLineCharacter, host: host, cancellationToken: cancellationToken, rulesProvider: rulesProvider });
+            });
+        }
+        function applyCodeActionCommand(fileName, action) {
+            fileName = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
+            switch (action.type) {
+                case "install package":
+                    return host.installPackage
+                        ? host.installPackage({ fileName: fileName, packageName: action.packageName })
+                        : Promise.reject("Host does not implement `installPackage`");
+                default:
+                    ts.Debug.fail();
+            }
+        }
+        function getDocCommentTemplateAtPosition(fileName, position) {
+            return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position);
+        }
+        function isValidBraceCompletionAtPosition(fileName, position, openingBrace) {
+            // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
+            // expensive to do during typing scenarios
+            // i.e. whether we're dealing with:
+            //      var x = new foo<| ( with class foo<T>{} )
+            // or
+            //      var y = 3 <|
+            if (openingBrace === 60 /* lessThan */) {
+                return false;
+            }
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            // Check if in a context where we don't want to perform any insertion
+            if (ts.isInString(sourceFile, position)) {
+                return false;
+            }
+            if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) {
+                return openingBrace === 123 /* openBrace */;
+            }
+            if (ts.isInTemplateString(sourceFile, position)) {
+                return false;
+            }
+            switch (openingBrace) {
+                case 39 /* singleQuote */:
+                case 34 /* doubleQuote */:
+                case 96 /* backtick */:
+                    return !ts.isInComment(sourceFile, position);
+            }
+            return true;
+        }
+        function getSpanOfEnclosingComment(fileName, position, onlyMultiLine) {
+            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+            var range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine);
+            return range && ts.createTextSpanFromRange(range);
+        }
+        function getTodoComments(fileName, descriptors) {
+            // Note: while getting todo comments seems like a syntactic operation, we actually
+            // treat it as a semantic operation here.  This is because we expect our host to call
+            // this on every single file.  If we treat this syntactically, then that will cause
+            // us to populate and throw away the tree in our syntax tree cache for each file.  By
+            // treating this as a semantic operation, we can access any tree without throwing
+            // anything away.
+            synchronizeHostData();
+            var sourceFile = getValidSourceFile(fileName);
+            cancellationToken.throwIfCancellationRequested();
+            var fileContents = sourceFile.text;
+            var result = [];
+            // Exclude node_modules files as we don't want to show the todos of external libraries.
+            if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) {
+                var regExp = getTodoCommentsRegExp();
+                var matchArray = void 0;
+                while (matchArray = regExp.exec(fileContents)) {
+                    cancellationToken.throwIfCancellationRequested();
+                    // If we got a match, here is what the match array will look like.  Say the source text is:
+                    //
+                    //      "    // hack   1"
+                    //
+                    // The result array with the regexp:    will be:
+                    //
+                    //      ["// hack   1", "// ", "hack   1", undefined, "hack"]
+                    //
+                    // Here are the relevant capture groups:
+                    //  0) The full match for the entire regexp.
+                    //  1) The preamble to the message portion.
+                    //  2) The message portion.
+                    //  3...N) The descriptor that was matched - by index.  'undefined' for each
+                    //         descriptor that didn't match.  an actual value if it did match.
+                    //
+                    //  i.e. 'undefined' in position 3 above means TODO(jason) didn't match.
+                    //       "hack"      in position 4 means HACK did match.
+                    var firstDescriptorCaptureIndex = 3;
+                    ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex);
+                    var preamble = matchArray[1];
+                    var matchPosition = matchArray.index + preamble.length;
+                    // OK, we have found a match in the file.  This is only an acceptable match if
+                    // it is contained within a comment.
+                    if (!ts.isInComment(sourceFile, matchPosition)) {
+                        continue;
+                    }
+                    var descriptor = undefined;
+                    for (var i = 0; i < descriptors.length; i++) {
+                        if (matchArray[i + firstDescriptorCaptureIndex]) {
+                            descriptor = descriptors[i];
+                        }
+                    }
+                    ts.Debug.assert(descriptor !== undefined);
+                    // We don't want to match something like 'TODOBY', so we make sure a non
+                    // letter/digit follows the match.
+                    if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) {
+                        continue;
+                    }
+                    var message = matchArray[2];
+                    result.push({ descriptor: descriptor, message: message, position: matchPosition });
+                }
+            }
+            return result;
+            function escapeRegExp(str) {
+                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+            }
+            function getTodoCommentsRegExp() {
+                // NOTE: ?:  means 'non-capture group'.  It allows us to have groups without having to
+                // filter them out later in the final result array.
+                // TODO comments can appear in one of the following forms:
+                //
+                //  1)      // TODO     or  /////////// TODO
+                //
+                //  2)      /* TODO     or  /********** TODO
+                //
+                //  3)      /*
+                //           *   TODO
+                //           */
+                //
+                // The following three regexps are used to match the start of the text up to the TODO
+                // comment portion.
+                var singleLineCommentStart = /(?:\/\/+\s*)/.source;
+                var multiLineCommentStart = /(?:\/\*+\s*)/.source;
+                var anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
+                // Match any of the above three TODO comment start regexps.
+                // Note that the outermost group *is* a capture group.  We want to capture the preamble
+                // so that we can determine the starting position of the TODO comment match.
+                var preamble = "(" + anyNumberOfSpacesAndAsterisksAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")";
+                // Takes the descriptors and forms a regexp that matches them as if they were literals.
+                // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be:
+                //
+                //      (?:(TODO\(jason\))|(HACK))
+                //
+                // Note that the outermost group is *not* a capture group, but the innermost groups
+                // *are* capture groups.  By capturing the inner literals we can determine after
+                // matching which descriptor we are dealing with.
+                var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")";
+                // After matching a descriptor literal, the following regexp matches the rest of the
+                // text up to the end of the line (or */).
+                var endOfLineOrEndOfComment = /(?:$|\*\/)/.source;
+                var messageRemainder = /(?:.*?)/.source;
+                // This is the portion of the match we'll return as part of the TODO comment result. We
+                // match the literal portion up to the end of the line or end of comment.
+                var messagePortion = "(" + literals + messageRemainder + ")";
+                var regExpString = preamble + messagePortion + endOfLineOrEndOfComment;
+                // The final regexp will look like this:
+                // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim
+                // The flags of the regexp are important here.
+                //  'g' is so that we are doing a global search and can find matches several times
+                //  in the input.
+                //
+                //  'i' is for case insensitivity (We do this to match C# TODO comment code).
+                //
+                //  'm' is so we can find matches in a multi-line input.
+                return new RegExp(regExpString, "gim");
+            }
+            function isLetterOrDigit(char) {
+                return (char >= 97 /* a */ && char <= 122 /* z */) ||
+                    (char >= 65 /* A */ && char <= 90 /* Z */) ||
+                    (char >= 48 /* _0 */ && char <= 57 /* _9 */);
+            }
+            function isNodeModulesFile(path) {
+                var node_modulesFolderName = "/node_modules/";
+                return ts.stringContains(path, node_modulesFolderName);
+            }
+        }
+        function getRenameInfo(fileName, position) {
+            synchronizeHostData();
+            var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings());
+            return ts.Rename.getRenameInfo(program.getTypeChecker(), defaultLibFileName, getCanonicalFileName, getValidSourceFile(fileName), position);
+        }
+        function getRefactorContext(file, positionOrRange, formatOptions) {
+            var _a = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end], startPosition = _a[0], endPosition = _a[1];
+            return {
+                file: file,
+                startPosition: startPosition,
+                endPosition: endPosition,
+                program: getProgram(),
+                newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
+                host: host,
+                rulesProvider: getRuleProvider(formatOptions),
+                cancellationToken: cancellationToken,
+            };
+        }
+        function getApplicableRefactors(fileName, positionOrRange) {
+            synchronizeHostData();
+            var file = getValidSourceFile(fileName);
+            return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange));
+        }
+        function getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName) {
+            synchronizeHostData();
+            var file = getValidSourceFile(fileName);
+            return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, formatOptions), refactorName, actionName);
+        }
+        return {
+            dispose: dispose,
+            cleanupSemanticCache: cleanupSemanticCache,
+            getSyntacticDiagnostics: getSyntacticDiagnostics,
+            getSemanticDiagnostics: getSemanticDiagnostics,
+            getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
+            getSyntacticClassifications: getSyntacticClassifications,
+            getSemanticClassifications: getSemanticClassifications,
+            getEncodedSyntacticClassifications: getEncodedSyntacticClassifications,
+            getEncodedSemanticClassifications: getEncodedSemanticClassifications,
+            getCompletionsAtPosition: getCompletionsAtPosition,
+            getCompletionEntryDetails: getCompletionEntryDetails,
+            getCompletionEntrySymbol: getCompletionEntrySymbol,
+            getSignatureHelpItems: getSignatureHelpItems,
+            getQuickInfoAtPosition: getQuickInfoAtPosition,
+            getDefinitionAtPosition: getDefinitionAtPosition,
+            getImplementationAtPosition: getImplementationAtPosition,
+            getTypeDefinitionAtPosition: getTypeDefinitionAtPosition,
+            getReferencesAtPosition: getReferencesAtPosition,
+            findReferences: findReferences,
+            getOccurrencesAtPosition: getOccurrencesAtPosition,
+            getDocumentHighlights: getDocumentHighlights,
+            getNameOrDottedNameSpan: getNameOrDottedNameSpan,
+            getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
+            getNavigateToItems: getNavigateToItems,
+            getRenameInfo: getRenameInfo,
+            findRenameLocations: findRenameLocations,
+            getNavigationBarItems: getNavigationBarItems,
+            getNavigationTree: getNavigationTree,
+            getOutliningSpans: getOutliningSpans,
+            getTodoComments: getTodoComments,
+            getBraceMatchingAtPosition: getBraceMatchingAtPosition,
+            getIndentationAtPosition: getIndentationAtPosition,
+            getFormattingEditsForRange: getFormattingEditsForRange,
+            getFormattingEditsForDocument: getFormattingEditsForDocument,
+            getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
+            getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition,
+            isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition,
+            getSpanOfEnclosingComment: getSpanOfEnclosingComment,
+            getCodeFixesAtPosition: getCodeFixesAtPosition,
+            applyCodeActionCommand: applyCodeActionCommand,
+            getEmitOutput: getEmitOutput,
+            getNonBoundSourceFile: getNonBoundSourceFile,
+            getSourceFile: getSourceFile,
+            getProgram: getProgram,
+            getApplicableRefactors: getApplicableRefactors,
+            getEditsForRefactor: getEditsForRefactor,
+        };
+    }
+    ts.createLanguageService = createLanguageService;
+    /* @internal */
+    /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */
+    function getNameTable(sourceFile) {
+        if (!sourceFile.nameTable) {
+            initializeNameTable(sourceFile);
+        }
+        return sourceFile.nameTable;
+    }
+    ts.getNameTable = getNameTable;
+    function initializeNameTable(sourceFile) {
+        var nameTable = sourceFile.nameTable = ts.createUnderscoreEscapedMap();
+        sourceFile.forEachChild(function walk(node) {
+            if (ts.isIdentifier(node) && node.escapedText || ts.isStringOrNumericLiteral(node) && literalIsName(node)) {
+                var text = ts.getEscapedTextOfIdentifierOrLiteral(node);
+                nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
+            }
+            ts.forEachChild(node, walk);
+            if (ts.hasJSDocNodes(node)) {
+                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
+                    var jsDoc = _a[_i];
+                    ts.forEachChild(jsDoc, walk);
+                }
+            }
+        });
+    }
+    /**
+     * We want to store any numbers/strings if they were a name that could be
+     * related to a declaration.  So, if we have 'import x = require("something")'
+     * then we want 'something' to be in the name table.  Similarly, if we have
+     * "a['propname']" then we want to store "propname" in the name table.
+     */
+    function literalIsName(node) {
+        return ts.isDeclarationName(node) ||
+            node.parent.kind === 248 /* ExternalModuleReference */ ||
+            isArgumentOfElementAccessExpression(node) ||
+            ts.isLiteralComputedPropertyDeclarationName(node);
+    }
+    function isObjectLiteralElement(node) {
+        switch (node.kind) {
+            case 253 /* JsxAttribute */:
+            case 255 /* JsxSpreadAttribute */:
+            case 261 /* PropertyAssignment */:
+            case 262 /* ShorthandPropertyAssignment */:
+            case 151 /* MethodDeclaration */:
+            case 153 /* GetAccessor */:
+            case 154 /* SetAccessor */:
+                return true;
+        }
+        return false;
+    }
+    /**
+     * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
+     */
+    /* @internal */
+    function getContainingObjectLiteralElement(node) {
+        switch (node.kind) {
+            case 9 /* StringLiteral */:
+            case 8 /* NumericLiteral */:
+                if (node.parent.kind === 144 /* ComputedPropertyName */) {
+                    return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
+                }
+            // falls through
+            case 71 /* Identifier */:
+                return isObjectLiteralElement(node.parent) &&
+                    (node.parent.parent.kind === 178 /* ObjectLiteralExpression */ || node.parent.parent.kind === 254 /* JsxAttributes */) &&
+                    node.parent.name === node ? node.parent : undefined;
+        }
+        return undefined;
+    }
+    ts.getContainingObjectLiteralElement = getContainingObjectLiteralElement;
+    /* @internal */
+    function getPropertySymbolsFromContextualType(typeChecker, node) {
+        var objectLiteral = node.parent;
+        var contextualType = typeChecker.getContextualType(objectLiteral);
+        return getPropertySymbolsFromType(contextualType, node.name);
+    }
+    ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType;
+    /* @internal */
+    function getPropertySymbolsFromType(type, propName) {
+        var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName));
+        if (name && type) {
+            var result_10 = [];
+            var symbol = type.getProperty(name);
+            if (type.flags & 65536 /* Union */) {
+                ts.forEach(type.types, function (t) {
+                    var symbol = t.getProperty(name);
+                    if (symbol) {
+                        result_10.push(symbol);
+                    }
+                });
+                return result_10;
+            }
+            if (symbol) {
+                result_10.push(symbol);
+                return result_10;
+            }
+        }
+        return undefined;
+    }
+    ts.getPropertySymbolsFromType = getPropertySymbolsFromType;
+    function isArgumentOfElementAccessExpression(node) {
+        return node &&
+            node.parent &&
+            node.parent.kind === 180 /* ElementAccessExpression */ &&
+            node.parent.argumentExpression === node;
+    }
+    /**
+     * Get the path of the default library files (lib.d.ts) as distributed with the typescript
+     * node package.
+     * The functionality is not supported if the ts module is consumed outside of a node module.
+     */
+    function getDefaultLibFilePath(options) {
+        // Check __dirname is defined and that we are on a node.js system.
+        if (typeof __dirname !== "undefined") {
+            return __dirname + ts.directorySeparator + ts.getDefaultLibFileName(options);
+        }
+        throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
+    }
+    ts.getDefaultLibFilePath = getDefaultLibFilePath;
+    ts.objectAllocator = getServicesObjectAllocator();
+})(ts || (ts = {}));
+// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
+// See LICENSE.txt in the project root for complete license information.
+/// <reference path='services.ts' />
+/* @internal */
+var ts;
+(function (ts) {
+    var BreakpointResolver;
+    (function (BreakpointResolver) {
+        /**
+         * Get the breakpoint span in given sourceFile
+         */
+        function spanInSourceFileAtLocation(sourceFile, position) {
+            // Cannot set breakpoint in dts file
+            if (sourceFile.isDeclarationFile) {
+                return undefined;
+            }
+            var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
+            var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
+            if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
+                // Get previous token if the token is returned starts on new line
+                // eg: let x =10; |--- cursor is here
+                //     let y = 10;
+                // token at position will return let keyword on second line as the token but we would like to use
+                // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
+                tokenAtLocation = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile);
+                // It's a blank line
+                if (!tokenAtLocation || sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) {
+                    return undefined;
+                }
+            }
+            // Cannot set breakpoint in ambient declarations
+            if (ts.isInAmbientContext(tokenAtLocation)) {
+                return undefined;
+            }
+            // Get the span in the node based on its syntax
+            return spanInNode(tokenAtLocation);
+            function textSpan(startNode, endNode) {
+                var start = startNode.decorators ?
+                    ts.skipTrivia(sourceFile.text, startNode.decorators.end) :
+                    startNode.getStart(sourceFile);
+                return ts.createTextSpanFromBounds(start, (endNode || startNode).getEnd());
+            }
+            function textSpanEndingAtNextToken(startNode, previousTokenToFindNextEndToken) {
+                return textSpan(startNode, ts.findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent));
+            }
+            function spanInNodeIfStartsOnSameLine(node, otherwiseOnNode) {
+                if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
+                    return spanInNode(node);
+                }
+                return spanInNode(otherwiseOnNode);
+            }
+            function spanInNodeArray(nodeArray) {
+                return ts.createTextSpanFromBounds(ts.skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
+            }
+            function spanInPreviousNode(node) {
+                return spanInNode(ts.findPrecedingToken(node.pos, sourceFile));
+            }
+            function spanInNextNode(node) {
+                return spanInNode(ts.findNextToken(node, node.parent));
+            }
+            function spanInNode(node) {
+                if (node) {
+                    switch (node.kind) {
+                        case 208 /* VariableStatement */:
+                            // Span on first variable declaration
+                            return spanInVariableDeclaration(node.declarationList.declarations[0]);
+                        case 226 /* VariableDeclaration */:
+                        case 149 /* PropertyDeclaration */:
+                        case 148 /* PropertySignature */:
+                            return spanInVariableDeclaration(node);
+                        case 146 /* Parameter */:
+                            return spanInParameterDeclaration(node);
+                        case 228 /* FunctionDeclaration */:
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                        case 152 /* Constructor */:
+                        case 186 /* FunctionExpression */:
+                        case 187 /* ArrowFunction */:
+                            return spanInFunctionDeclaration(node);
+                        case 207 /* Block */:
+                            if (ts.isFunctionBlock(node)) {
+                                return spanInFunctionBlock(node);
+                            }
+                        // falls through
+                        case 234 /* ModuleBlock */:
+                            return spanInBlock(node);
+                        case 260 /* CatchClause */:
+                            return spanInBlock(node.block);
+                        case 210 /* ExpressionStatement */:
+                            // span on the expression
+                            return textSpan(node.expression);
+                        case 219 /* ReturnStatement */:
+                            // span on return keyword and expression if present
+                            return textSpan(node.getChildAt(0), node.expression);
+                        case 213 /* WhileStatement */:
+                            // Span on while(...)
+                            return textSpanEndingAtNextToken(node, node.expression);
+                        case 212 /* DoStatement */:
+                            // span in statement of the do statement
+                            return spanInNode(node.statement);
+                        case 225 /* DebuggerStatement */:
+                            // span on debugger keyword
+                            return textSpan(node.getChildAt(0));
+                        case 211 /* IfStatement */:
+                            // set on if(..) span
+                            return textSpanEndingAtNextToken(node, node.expression);
+                        case 222 /* LabeledStatement */:
+                            // span in statement
+                            return spanInNode(node.statement);
+                        case 218 /* BreakStatement */:
+                        case 217 /* ContinueStatement */:
+                            // On break or continue keyword and label if present
+                            return textSpan(node.getChildAt(0), node.label);
+                        case 214 /* ForStatement */:
+                            return spanInForStatement(node);
+                        case 215 /* ForInStatement */:
+                            // span of for (a in ...)
+                            return textSpanEndingAtNextToken(node, node.expression);
+                        case 216 /* ForOfStatement */:
+                            // span in initializer
+                            return spanInInitializerOfForLike(node);
+                        case 221 /* SwitchStatement */:
+                            // span on switch(...)
+                            return textSpanEndingAtNextToken(node, node.expression);
+                        case 257 /* CaseClause */:
+                        case 258 /* DefaultClause */:
+                            // span in first statement of the clause
+                            return spanInNode(node.statements[0]);
+                        case 224 /* TryStatement */:
+                            // span in try block
+                            return spanInBlock(node.tryBlock);
+                        case 223 /* ThrowStatement */:
+                            // span in throw ...
+                            return textSpan(node, node.expression);
+                        case 243 /* ExportAssignment */:
+                            // span on export = id
+                            return textSpan(node, node.expression);
+                        case 237 /* ImportEqualsDeclaration */:
+                            // import statement without including semicolon
+                            return textSpan(node, node.moduleReference);
+                        case 238 /* ImportDeclaration */:
+                            // import statement without including semicolon
+                            return textSpan(node, node.moduleSpecifier);
+                        case 244 /* ExportDeclaration */:
+                            // import statement without including semicolon
+                            return textSpan(node, node.moduleSpecifier);
+                        case 233 /* ModuleDeclaration */:
+                            // span on complete module if it is instantiated
+                            if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
+                                return undefined;
+                            }
+                        // falls through
+                        case 229 /* ClassDeclaration */:
+                        case 232 /* EnumDeclaration */:
+                        case 264 /* EnumMember */:
+                        case 176 /* BindingElement */:
+                            // span on complete node
+                            return textSpan(node);
+                        case 220 /* WithStatement */:
+                            // span in statement
+                            return spanInNode(node.statement);
+                        case 147 /* Decorator */:
+                            return spanInNodeArray(node.parent.decorators);
+                        case 174 /* ObjectBindingPattern */:
+                        case 175 /* ArrayBindingPattern */:
+                            return spanInBindingPattern(node);
+                        // No breakpoint in interface, type alias
+                        case 230 /* InterfaceDeclaration */:
+                        case 231 /* TypeAliasDeclaration */:
+                            return undefined;
+                        // Tokens:
+                        case 25 /* SemicolonToken */:
+                        case 1 /* EndOfFileToken */:
+                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
+                        case 26 /* CommaToken */:
+                            return spanInPreviousNode(node);
+                        case 17 /* OpenBraceToken */:
+                            return spanInOpenBraceToken(node);
+                        case 18 /* CloseBraceToken */:
+                            return spanInCloseBraceToken(node);
+                        case 22 /* CloseBracketToken */:
+                            return spanInCloseBracketToken(node);
+                        case 19 /* OpenParenToken */:
+                            return spanInOpenParenToken(node);
+                        case 20 /* CloseParenToken */:
+                            return spanInCloseParenToken(node);
+                        case 56 /* ColonToken */:
+                            return spanInColonToken(node);
+                        case 29 /* GreaterThanToken */:
+                        case 27 /* LessThanToken */:
+                            return spanInGreaterThanOrLessThanToken(node);
+                        // Keywords:
+                        case 106 /* WhileKeyword */:
+                            return spanInWhileKeyword(node);
+                        case 82 /* ElseKeyword */:
+                        case 74 /* CatchKeyword */:
+                        case 87 /* FinallyKeyword */:
+                            return spanInNextNode(node);
+                        case 142 /* OfKeyword */:
+                            return spanInOfKeyword(node);
+                        default:
+                            // Destructuring pattern in destructuring assignment
+                            // [a, b, c] of
+                            // [a, b, c] = expression
+                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node)) {
+                                return spanInArrayLiteralOrObjectLiteralDestructuringPattern(node);
+                            }
+                            // Set breakpoint on identifier element of destructuring pattern
+                            // a or ...c  or d: x from
+                            // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern
+                            if ((node.kind === 71 /* Identifier */ ||
+                                node.kind === 198 /* SpreadElement */ ||
+                                node.kind === 261 /* PropertyAssignment */ ||
+                                node.kind === 262 /* ShorthandPropertyAssignment */) &&
+                                ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
+                                return textSpan(node);
+                            }
+                            if (node.kind === 194 /* BinaryExpression */) {
+                                var binaryExpression = node;
+                                // Set breakpoint in destructuring pattern if its destructuring assignment
+                                // [a, b, c] or {a, b, c} of
+                                // [a, b, c] = expression or
+                                // {a, b, c} = expression
+                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) {
+                                    return spanInArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left);
+                                }
+                                if (binaryExpression.operatorToken.kind === 58 /* EqualsToken */ &&
+                                    ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) {
+                                    // Set breakpoint on assignment expression element of destructuring pattern
+                                    // a = expression of
+                                    // [a = expression, b, c] = someExpression or
+                                    // { a = expression, b, c } = someExpression
+                                    return textSpan(node);
+                                }
+                                if (binaryExpression.operatorToken.kind === 26 /* CommaToken */) {
+                                    return spanInNode(binaryExpression.left);
+                                }
+                            }
+                            if (ts.isPartOfExpression(node)) {
+                                switch (node.parent.kind) {
+                                    case 212 /* DoStatement */:
+                                        // Set span as if on while keyword
+                                        return spanInPreviousNode(node);
+                                    case 147 /* Decorator */:
+                                        // Set breakpoint on the decorator emit
+                                        return spanInNode(node.parent);
+                                    case 214 /* ForStatement */:
+                                    case 216 /* ForOfStatement */:
+                                        return textSpan(node);
+                                    case 194 /* BinaryExpression */:
+                                        if (node.parent.operatorToken.kind === 26 /* CommaToken */) {
+                                            // If this is a comma expression, the breakpoint is possible in this expression
+                                            return textSpan(node);
+                                        }
+                                        break;
+                                    case 187 /* ArrowFunction */:
+                                        if (node.parent.body === node) {
+                                            // If this is body of arrow function, it is allowed to have the breakpoint
+                                            return textSpan(node);
+                                        }
+                                        break;
+                                }
+                            }
+                            // If this is name of property assignment, set breakpoint in the initializer
+                            if (node.parent.kind === 261 /* PropertyAssignment */ &&
+                                node.parent.name === node &&
+                                !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
+                                return spanInNode(node.parent.initializer);
+                            }
+                            // Breakpoint in type assertion goes to its operand
+                            if (node.parent.kind === 184 /* TypeAssertionExpression */ && node.parent.type === node) {
+                                return spanInNextNode(node.parent.type);
+                            }
+                            // return type of function go to previous token
+                            if (ts.isFunctionLike(node.parent) && node.parent.type === node) {
+                                return spanInPreviousNode(node);
+                            }
+                            // initializer of variable/parameter declaration go to previous node
+                            if ((node.parent.kind === 226 /* VariableDeclaration */ ||
+                                node.parent.kind === 146 /* Parameter */)) {
+                                var paramOrVarDecl = node.parent;
+                                if (paramOrVarDecl.initializer === node ||
+                                    paramOrVarDecl.type === node ||
+                                    ts.isAssignmentOperator(node.kind)) {
+                                    return spanInPreviousNode(node);
+                                }
+                            }
+                            if (node.parent.kind === 194 /* BinaryExpression */) {
+                                var binaryExpression = node.parent;
+                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left) &&
+                                    (binaryExpression.right === node ||
+                                        binaryExpression.operatorToken === node)) {
+                                    // If initializer of destructuring assignment move to previous token
+                                    return spanInPreviousNode(node);
+                                }
+                            }
+                            // Default go to parent to set the breakpoint
+                            return spanInNode(node.parent);
+                    }
+                }
+                function textSpanFromVariableDeclaration(variableDeclaration) {
+                    if (variableDeclaration.parent.kind === 227 /* VariableDeclarationList */ &&
+                        variableDeclaration.parent.declarations[0] === variableDeclaration) {
+                        // First declaration - include let keyword
+                        return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
+                    }
+                    else {
+                        // Span only on this declaration
+                        return textSpan(variableDeclaration);
+                    }
+                }
+                function spanInVariableDeclaration(variableDeclaration) {
+                    // If declaration of for in statement, just set the span in parent
+                    if (variableDeclaration.parent.parent.kind === 215 /* ForInStatement */) {
+                        return spanInNode(variableDeclaration.parent.parent);
+                    }
+                    // If this is a destructuring pattern, set breakpoint in binding pattern
+                    if (ts.isBindingPattern(variableDeclaration.name)) {
+                        return spanInBindingPattern(variableDeclaration.name);
+                    }
+                    // Breakpoint is possible in variableDeclaration only if there is initialization
+                    // or its declaration from 'for of'
+                    if (variableDeclaration.initializer ||
+                        ts.hasModifier(variableDeclaration, 1 /* Export */) ||
+                        variableDeclaration.parent.parent.kind === 216 /* ForOfStatement */) {
+                        return textSpanFromVariableDeclaration(variableDeclaration);
+                    }
+                    if (variableDeclaration.parent.kind === 227 /* VariableDeclarationList */ &&
+                        variableDeclaration.parent.declarations[0] !== variableDeclaration) {
+                        // If we cannot set breakpoint on this declaration, set it on previous one
+                        // Because the variable declaration may be binding pattern and
+                        // we would like to set breakpoint in last binding element if that's the case,
+                        // use preceding token instead
+                        return spanInNode(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
+                    }
+                }
+                function canHaveSpanInParameterDeclaration(parameter) {
+                    // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier
+                    return !!parameter.initializer || parameter.dotDotDotToken !== undefined ||
+                        ts.hasModifier(parameter, 4 /* Public */ | 8 /* Private */);
+                }
+                function spanInParameterDeclaration(parameter) {
+                    if (ts.isBindingPattern(parameter.name)) {
+                        // Set breakpoint in binding pattern
+                        return spanInBindingPattern(parameter.name);
+                    }
+                    else if (canHaveSpanInParameterDeclaration(parameter)) {
+                        return textSpan(parameter);
+                    }
+                    else {
+                        var functionDeclaration = parameter.parent;
+                        var indexOfParameter = ts.indexOf(functionDeclaration.parameters, parameter);
+                        if (indexOfParameter) {
+                            // Not a first parameter, go to previous parameter
+                            return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]);
+                        }
+                        else {
+                            // Set breakpoint in the function declaration body
+                            return spanInNode(functionDeclaration.body);
+                        }
+                    }
+                }
+                function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) {
+                    return ts.hasModifier(functionDeclaration, 1 /* Export */) ||
+                        (functionDeclaration.parent.kind === 229 /* ClassDeclaration */ && functionDeclaration.kind !== 152 /* Constructor */);
+                }
+                function spanInFunctionDeclaration(functionDeclaration) {
+                    // No breakpoints in the function signature
+                    if (!functionDeclaration.body) {
+                        return undefined;
+                    }
+                    if (canFunctionHaveSpanInWholeDeclaration(functionDeclaration)) {
+                        // Set the span on whole function declaration
+                        return textSpan(functionDeclaration);
+                    }
+                    // Set span in function body
+                    return spanInNode(functionDeclaration.body);
+                }
+                function spanInFunctionBlock(block) {
+                    var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
+                    if (canFunctionHaveSpanInWholeDeclaration(block.parent)) {
+                        return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
+                    }
+                    return spanInNode(nodeForSpanInBlock);
+                }
+                function spanInBlock(block) {
+                    switch (block.parent.kind) {
+                        case 233 /* ModuleDeclaration */:
+                            if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
+                                return undefined;
+                            }
+                        // falls through
+                        // Set on parent if on same line otherwise on first statement
+                        case 213 /* WhileStatement */:
+                        case 211 /* IfStatement */:
+                        case 215 /* ForInStatement */:
+                            return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
+                        // Set span on previous token if it starts on same line otherwise on the first statement of the block
+                        case 214 /* ForStatement */:
+                        case 216 /* ForOfStatement */:
+                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(block.pos, sourceFile, block.parent), block.statements[0]);
+                    }
+                    // Default action is to set on first statement
+                    return spanInNode(block.statements[0]);
+                }
+                function spanInInitializerOfForLike(forLikeStatement) {
+                    if (forLikeStatement.initializer.kind === 227 /* VariableDeclarationList */) {
+                        // Declaration list - set breakpoint in first declaration
+                        var variableDeclarationList = forLikeStatement.initializer;
+                        if (variableDeclarationList.declarations.length > 0) {
+                            return spanInNode(variableDeclarationList.declarations[0]);
+                        }
+                    }
+                    else {
+                        // Expression - set breakpoint in it
+                        return spanInNode(forLikeStatement.initializer);
+                    }
+                }
+                function spanInForStatement(forStatement) {
+                    if (forStatement.initializer) {
+                        return spanInInitializerOfForLike(forStatement);
+                    }
+                    if (forStatement.condition) {
+                        return textSpan(forStatement.condition);
+                    }
+                    if (forStatement.incrementor) {
+                        return textSpan(forStatement.incrementor);
+                    }
+                }
+                function spanInBindingPattern(bindingPattern) {
+                    // Set breakpoint in first binding element
+                    var firstBindingElement = ts.forEach(bindingPattern.elements, function (element) { return element.kind !== 200 /* OmittedExpression */ ? element : undefined; });
+                    if (firstBindingElement) {
+                        return spanInNode(firstBindingElement);
+                    }
+                    // Empty binding pattern of binding element, set breakpoint on binding element
+                    if (bindingPattern.parent.kind === 176 /* BindingElement */) {
+                        return textSpan(bindingPattern.parent);
+                    }
+                    // Variable declaration is used as the span
+                    return textSpanFromVariableDeclaration(bindingPattern.parent);
+                }
+                function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) {
+                    ts.Debug.assert(node.kind !== 175 /* ArrayBindingPattern */ && node.kind !== 174 /* ObjectBindingPattern */);
+                    var elements = node.kind === 177 /* ArrayLiteralExpression */ ?
+                        node.elements :
+                        node.properties;
+                    var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 200 /* OmittedExpression */ ? element : undefined; });
+                    if (firstBindingElement) {
+                        return spanInNode(firstBindingElement);
+                    }
+                    // Could be ArrayLiteral from destructuring assignment or
+                    // just nested element in another destructuring assignment
+                    // set breakpoint on assignment when parent is destructuring assignment
+                    // Otherwise set breakpoint for this element
+                    return textSpan(node.parent.kind === 194 /* BinaryExpression */ ? node.parent : node);
+                }
+                // Tokens:
+                function spanInOpenBraceToken(node) {
+                    switch (node.parent.kind) {
+                        case 232 /* EnumDeclaration */:
+                            var enumDeclaration = node.parent;
+                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
+                        case 229 /* ClassDeclaration */:
+                            var classDeclaration = node.parent;
+                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
+                        case 235 /* CaseBlock */:
+                            return spanInNodeIfStartsOnSameLine(node.parent.parent, node.parent.clauses[0]);
+                    }
+                    // Default to parent node
+                    return spanInNode(node.parent);
+                }
+                function spanInCloseBraceToken(node) {
+                    switch (node.parent.kind) {
+                        case 234 /* ModuleBlock */:
+                            // If this is not an instantiated module block, no bp span
+                            if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
+                                return undefined;
+                            }
+                        // falls through
+                        case 232 /* EnumDeclaration */:
+                        case 229 /* ClassDeclaration */:
+                            // Span on close brace token
+                            return textSpan(node);
+                        case 207 /* Block */:
+                            if (ts.isFunctionBlock(node.parent)) {
+                                // Span on close brace token
+                                return textSpan(node);
+                            }
+                        // falls through
+                        case 260 /* CatchClause */:
+                            return spanInNode(ts.lastOrUndefined(node.parent.statements));
+                        case 235 /* CaseBlock */:
+                            // breakpoint in last statement of the last clause
+                            var caseBlock = node.parent;
+                            var lastClause = ts.lastOrUndefined(caseBlock.clauses);
+                            if (lastClause) {
+                                return spanInNode(ts.lastOrUndefined(lastClause.statements));
+                            }
+                            return undefined;
+                        case 174 /* ObjectBindingPattern */:
+                            // Breakpoint in last binding element or binding pattern if it contains no elements
+                            var bindingPattern = node.parent;
+                            return spanInNode(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
+                        // Default to parent node
+                        default:
+                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
+                                // Breakpoint in last binding element or binding pattern if it contains no elements
+                                var objectLiteral = node.parent;
+                                return textSpan(ts.lastOrUndefined(objectLiteral.properties) || objectLiteral);
+                            }
+                            return spanInNode(node.parent);
+                    }
+                }
+                function spanInCloseBracketToken(node) {
+                    switch (node.parent.kind) {
+                        case 175 /* ArrayBindingPattern */:
+                            // Breakpoint in last binding element or binding pattern if it contains no elements
+                            var bindingPattern = node.parent;
+                            return textSpan(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
+                        default:
+                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
+                                // Breakpoint in last binding element or binding pattern if it contains no elements
+                                var arrayLiteral = node.parent;
+                                return textSpan(ts.lastOrUndefined(arrayLiteral.elements) || arrayLiteral);
+                            }
+                            // Default to parent node
+                            return spanInNode(node.parent);
+                    }
+                }
+                function spanInOpenParenToken(node) {
+                    if (node.parent.kind === 212 /* DoStatement */ || // Go to while keyword and do action instead
+                        node.parent.kind === 181 /* CallExpression */ ||
+                        node.parent.kind === 182 /* NewExpression */) {
+                        return spanInPreviousNode(node);
+                    }
+                    if (node.parent.kind === 185 /* ParenthesizedExpression */) {
+                        return spanInNextNode(node);
+                    }
+                    // Default to parent node
+                    return spanInNode(node.parent);
+                }
+                function spanInCloseParenToken(node) {
+                    // Is this close paren token of parameter list, set span in previous token
+                    switch (node.parent.kind) {
+                        case 186 /* FunctionExpression */:
+                        case 228 /* FunctionDeclaration */:
+                        case 187 /* ArrowFunction */:
+                        case 151 /* MethodDeclaration */:
+                        case 150 /* MethodSignature */:
+                        case 153 /* GetAccessor */:
+                        case 154 /* SetAccessor */:
+                        case 152 /* Constructor */:
+                        case 213 /* WhileStatement */:
+                        case 212 /* DoStatement */:
+                        case 214 /* ForStatement */:
+                        case 216 /* ForOfStatement */:
+                        case 181 /* CallExpression */:
+                        case 182 /* NewExpression */:
+                        case 185 /* ParenthesizedExpression */:
+                            return spanInPreviousNode(node);
+                        // Default to parent node
+                        default:
+                            return spanInNode(node.parent);
+                    }
+                }
+                function spanInColonToken(node) {
+                    // Is this : specifying return annotation of the function declaration
+                    if (ts.isFunctionLike(node.parent) ||
+                        node.parent.kind === 261 /* PropertyAssignment */ ||
+                        node.parent.kind === 146 /* Parameter */) {
+                        return spanInPreviousNode(node);
+                    }
+                    return spanInNode(node.parent);
+                }
+                function spanInGreaterThanOrLessThanToken(node) {
+                    if (node.parent.kind === 184 /* TypeAssertionExpression */) {
+                        return spanInNextNode(node);
+                    }
+                    return spanInNode(node.parent);
+                }
+                function spanInWhileKeyword(node) {
+                    if (node.parent.kind === 212 /* DoStatement */) {
+                        // Set span on while expression
+                        return textSpanEndingAtNextToken(node, node.parent.expression);
+                    }
+                    // Default to parent node
+                    return spanInNode(node.parent);
+                }
+                function spanInOfKeyword(node) {
+                    if (node.parent.kind === 216 /* ForOfStatement */) {
+                        // Set using next token
+                        return spanInNextNode(node);
+                    }
+                    // Default to parent node
+                    return spanInNode(node.parent);
+                }
+            }
+        }
+        BreakpointResolver.spanInSourceFileAtLocation = spanInSourceFileAtLocation;
+    })(BreakpointResolver = ts.BreakpointResolver || (ts.BreakpointResolver = {}));
+})(ts || (ts = {}));
+/// <reference path="..\compiler\transformer.ts"/>
+/// <reference path="transpile.ts"/>
+var ts;
+(function (ts) {
+    /**
+     * Transform one or more nodes using the supplied transformers.
+     * @param source A single `Node` or an array of `Node` objects.
+     * @param transformers An array of `TransformerFactory` callbacks used to process the transformation.
+     * @param compilerOptions Optional compiler options.
+     */
+    function transform(source, transformers, compilerOptions) {
+        var diagnostics = [];
+        compilerOptions = ts.fixupCompilerOptions(compilerOptions, diagnostics);
+        var nodes = ts.isArray(source) ? source : [source];
+        var result = ts.transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
+        result.diagnostics = ts.concatenate(result.diagnostics, diagnostics);
+        return result;
+    }
+    ts.transform = transform;
+})(ts || (ts = {}));
+//
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+/// <reference path='services.ts' />
+/* @internal */
+var debugObjectHost = (function () { return this; })();
+// We need to use 'null' to interface with the managed side.
+/* tslint:disable:no-null-keyword */
+/* tslint:disable:no-in-operator */
+/* @internal */
+var ts;
+(function (ts) {
+    function logInternalError(logger, err) {
+        if (logger) {
+            logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
+        }
+    }
+    var ScriptSnapshotShimAdapter = /** @class */ (function () {
+        function ScriptSnapshotShimAdapter(scriptSnapshotShim) {
+            this.scriptSnapshotShim = scriptSnapshotShim;
+        }
+        ScriptSnapshotShimAdapter.prototype.getText = function (start, end) {
+            return this.scriptSnapshotShim.getText(start, end);
+        };
+        ScriptSnapshotShimAdapter.prototype.getLength = function () {
+            return this.scriptSnapshotShim.getLength();
+        };
+        ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) {
+            var oldSnapshotShim = oldSnapshot;
+            var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
+            if (encoded === null) {
+                return null;
+            }
+            var decoded = JSON.parse(encoded);
+            return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
+        };
+        ScriptSnapshotShimAdapter.prototype.dispose = function () {
+            // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments
+            // 'in' does not have this effect
+            if ("dispose" in this.scriptSnapshotShim) {
+                this.scriptSnapshotShim.dispose();
+            }
+        };
+        return ScriptSnapshotShimAdapter;
+    }());
+    var LanguageServiceShimHostAdapter = /** @class */ (function () {
+        function LanguageServiceShimHostAdapter(shimHost) {
+            var _this = this;
+            this.shimHost = shimHost;
+            this.loggingEnabled = false;
+            this.tracingEnabled = false;
+            // if shimHost is a COM object then property check will become method call with no arguments.
+            // 'in' does not have this effect.
+            if ("getModuleResolutionsForFile" in this.shimHost) {
+                this.resolveModuleNames = function (moduleNames, containingFile) {
+                    var resolutionsInFile = JSON.parse(_this.shimHost.getModuleResolutionsForFile(containingFile));
+                    return ts.map(moduleNames, function (name) {
+                        var result = ts.getProperty(resolutionsInFile, name);
+                        return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined;
+                    });
+                };
+            }
+            if ("directoryExists" in this.shimHost) {
+                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
+            }
+            if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
+                this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) {
+                    var typeDirectivesForFile = JSON.parse(_this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile));
+                    return ts.map(typeDirectiveNames, function (name) { return ts.getProperty(typeDirectivesForFile, name); });
+                };
+            }
+        }
+        LanguageServiceShimHostAdapter.prototype.log = function (s) {
+            if (this.loggingEnabled) {
+                this.shimHost.log(s);
+            }
+        };
+        LanguageServiceShimHostAdapter.prototype.trace = function (s) {
+            if (this.tracingEnabled) {
+                this.shimHost.trace(s);
+            }
+        };
+        LanguageServiceShimHostAdapter.prototype.error = function (s) {
+            this.shimHost.error(s);
+        };
+        LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () {
+            if (!this.shimHost.getProjectVersion) {
+                // shimmed host does not support getProjectVersion
+                return undefined;
+            }
+            return this.shimHost.getProjectVersion();
+        };
+        LanguageServiceShimHostAdapter.prototype.getTypeRootsVersion = function () {
+            if (!this.shimHost.getTypeRootsVersion) {
+                return 0;
+            }
+            return this.shimHost.getTypeRootsVersion();
+        };
+        LanguageServiceShimHostAdapter.prototype.useCaseSensitiveFileNames = function () {
+            return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
+        };
+        LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
+            var settingsJson = this.shimHost.getCompilationSettings();
+            if (settingsJson === null || settingsJson === "") {
+                throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
+            }
+            var compilerOptions = JSON.parse(settingsJson);
+            // permit language service to handle all files (filtering should be performed on the host side)
+            compilerOptions.allowNonTsExtensions = true;
+            return compilerOptions;
+        };
+        LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () {
+            var encoded = this.shimHost.getScriptFileNames();
+            return this.files = JSON.parse(encoded);
+        };
+        LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) {
+            var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName);
+            return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot);
+        };
+        LanguageServiceShimHostAdapter.prototype.getScriptKind = function (fileName) {
+            if ("getScriptKind" in this.shimHost) {
+                return this.shimHost.getScriptKind(fileName);
+            }
+            else {
+                return 0 /* Unknown */;
+            }
+        };
+        LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) {
+            return this.shimHost.getScriptVersion(fileName);
+        };
+        LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () {
+            var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
+            if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") {
+                return null;
+            }
+            try {
+                return JSON.parse(diagnosticMessagesJson);
+            }
+            catch (e) {
+                this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
+                return null;
+            }
+        };
+        LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () {
+            var hostCancellationToken = this.shimHost.getCancellationToken();
+            return new ts.ThrottledCancellationToken(hostCancellationToken);
+        };
+        LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () {
+            return this.shimHost.getCurrentDirectory();
+        };
+        LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) {
+            return JSON.parse(this.shimHost.getDirectories(path));
+        };
+        LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) {
+            return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
+        };
+        LanguageServiceShimHostAdapter.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
+            var pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
+            return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
+        };
+        LanguageServiceShimHostAdapter.prototype.readFile = function (path, encoding) {
+            return this.shimHost.readFile(path, encoding);
+        };
+        LanguageServiceShimHostAdapter.prototype.fileExists = function (path) {
+            return this.shimHost.fileExists(path);
+        };
+        return LanguageServiceShimHostAdapter;
+    }());
+    ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
+    var CoreServicesShimHostAdapter = /** @class */ (function () {
+        function CoreServicesShimHostAdapter(shimHost) {
+            var _this = this;
+            this.shimHost = shimHost;
+            this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
+            if ("directoryExists" in this.shimHost) {
+                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
+            }
+            if ("realpath" in this.shimHost) {
+                this.realpath = function (path) { return _this.shimHost.realpath(path); };
+            }
+        }
+        CoreServicesShimHostAdapter.prototype.readDirectory = function (rootDir, extensions, exclude, include, depth) {
+            var pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
+            return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
+        };
+        CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) {
+            return this.shimHost.fileExists(fileName);
+        };
+        CoreServicesShimHostAdapter.prototype.readFile = function (fileName) {
+            return this.shimHost.readFile(fileName);
+        };
+        CoreServicesShimHostAdapter.prototype.getDirectories = function (path) {
+            return JSON.parse(this.shimHost.getDirectories(path));
+        };
+        return CoreServicesShimHostAdapter;
+    }());
+    ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter;
+    function simpleForwardCall(logger, actionDescription, action, logPerformance) {
+        var start;
+        if (logPerformance) {
+            logger.log(actionDescription);
+            start = ts.timestamp();
+        }
+        var result = action();
+        if (logPerformance) {
+            var end = ts.timestamp();
+            logger.log(actionDescription + " completed in " + (end - start) + " msec");
+            if (ts.isString(result)) {
+                var str = result;
+                if (str.length > 128) {
+                    str = str.substring(0, 128) + "...";
+                }
+                logger.log("  result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
+            }
+        }
+        return result;
+    }
+    function forwardJSONCall(logger, actionDescription, action, logPerformance) {
+        return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance);
+    }
+    function forwardCall(logger, actionDescription, returnJson, action, logPerformance) {
+        try {
+            var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
+            return returnJson ? JSON.stringify({ result: result }) : result;
+        }
+        catch (err) {
+            if (err instanceof ts.OperationCanceledException) {
+                return JSON.stringify({ canceled: true });
+            }
+            logInternalError(logger, err);
+            err.description = actionDescription;
+            return JSON.stringify({ error: err });
+        }
+    }
+    var ShimBase = /** @class */ (function () {
+        function ShimBase(factory) {
+            this.factory = factory;
+            factory.registerShim(this);
+        }
+        ShimBase.prototype.dispose = function (_dummy) {
+            this.factory.unregisterShim(this);
+        };
+        return ShimBase;
+    }());
+    function realizeDiagnostics(diagnostics, newLine) {
+        return diagnostics.map(function (d) { return realizeDiagnostic(d, newLine); });
+    }
+    ts.realizeDiagnostics = realizeDiagnostics;
+    function realizeDiagnostic(diagnostic, newLine) {
+        return {
+            message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine),
+            start: diagnostic.start,
+            length: diagnostic.length,
+            /// TODO: no need for the tolowerCase call
+            category: ts.DiagnosticCategory[diagnostic.category].toLowerCase(),
+            code: diagnostic.code
+        };
+    }
+    var LanguageServiceShimObject = /** @class */ (function (_super) {
+        __extends(LanguageServiceShimObject, _super);
+        function LanguageServiceShimObject(factory, host, languageService) {
+            var _this = _super.call(this, factory) || this;
+            _this.host = host;
+            _this.languageService = languageService;
+            _this.logPerformance = false;
+            _this.logger = _this.host;
+            return _this;
+        }
+        LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
+            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
+        };
+        /// DISPOSE
+        /**
+         * Ensure (almost) deterministic release of internal Javascript resources when
+         * some external native objects holds onto us (e.g. Com/Interop).
+         */
+        LanguageServiceShimObject.prototype.dispose = function (dummy) {
+            this.logger.log("dispose()");
+            this.languageService.dispose();
+            this.languageService = null;
+            // force a GC
+            if (debugObjectHost && debugObjectHost.CollectGarbage) {
+                debugObjectHost.CollectGarbage();
+                this.logger.log("CollectGarbage()");
+            }
+            this.logger = null;
+            _super.prototype.dispose.call(this, dummy);
+        };
+        /// REFRESH
+        /**
+         * Update the list of scripts known to the compiler
+         */
+        LanguageServiceShimObject.prototype.refresh = function (throwOnError) {
+            this.forwardJSONCall("refresh(" + throwOnError + ")", function () { return null; });
+        };
+        LanguageServiceShimObject.prototype.cleanupSemanticCache = function () {
+            var _this = this;
+            this.forwardJSONCall("cleanupSemanticCache()", function () {
+                _this.languageService.cleanupSemanticCache();
+                return null;
+            });
+        };
+        LanguageServiceShimObject.prototype.realizeDiagnostics = function (diagnostics) {
+            var newLine = ts.getNewLineOrDefaultFromHost(this.host);
+            return ts.realizeDiagnostics(diagnostics, newLine);
+        };
+        LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) {
+            var _this = this;
+            return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length)); });
+        };
+        LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) {
+            var _this = this;
+            return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length)); });
+        };
+        LanguageServiceShimObject.prototype.getEncodedSyntacticClassifications = function (fileName, start, length) {
+            var _this = this;
+            return this.forwardJSONCall("getEncodedSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", 
+            // directly serialize the spans out to a string.  This is much faster to decode
+            // on the managed side versus a full JSON array.
+            function () { return convertClassifications(_this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length))); });
+        };
+        LanguageServiceShimObject.prototype.getEncodedSemanticClassifications = function (fileName, start, length) {
+            var _this = this;
+            return this.forwardJSONCall("getEncodedSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", 
+            // directly serialize the spans out to a string.  This is much faster to decode
+            // on the managed side versus a full JSON array.
+            function () { return convertClassifications(_this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length))); });
+        };
+        LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () {
+                var diagnostics = _this.languageService.getSyntacticDiagnostics(fileName);
+                return _this.realizeDiagnostics(diagnostics);
+            });
+        };
+        LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () {
+                var diagnostics = _this.languageService.getSemanticDiagnostics(fileName);
+                return _this.realizeDiagnostics(diagnostics);
+            });
+        };
+        LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () {
+            var _this = this;
+            return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () {
+                var diagnostics = _this.languageService.getCompilerOptionsDiagnostics();
+                return _this.realizeDiagnostics(diagnostics);
+            });
+        };
+        /// QUICKINFO
+        /**
+         * Computes a string representation of the type at the requested position
+         * in the active file.
+         */
+        LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); });
+        };
+        /// NAMEORDOTTEDNAMESPAN
+        /**
+         * Computes span information of the name or dotted name at the requested position
+         * in the active file.
+         */
+        LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) {
+            var _this = this;
+            return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () { return _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos); });
+        };
+        /**
+         * STATEMENTSPAN
+         * Computes span information of statement at the requested position in the active file.
+         */
+        LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBreakpointStatementAtPosition(fileName, position); });
+        };
+        /// SIGNATUREHELP
+        LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () { return _this.languageService.getSignatureHelpItems(fileName, position); });
+        };
+        /// GOTO DEFINITION
+        /**
+         * Computes the definition location and file for the symbol
+         * at the requested position.
+         */
+        LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAtPosition(fileName, position); });
+        };
+        /// GOTO Type
+        /**
+         * Computes the definition location of the type of the symbol
+         * at the requested position.
+         */
+        LanguageServiceShimObject.prototype.getTypeDefinitionAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getTypeDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getTypeDefinitionAtPosition(fileName, position); });
+        };
+        /// GOTO Implementation
+        /**
+         * Computes the implementation location of the symbol
+         * at the requested position.
+         */
+        LanguageServiceShimObject.prototype.getImplementationAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getImplementationAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getImplementationAtPosition(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () { return _this.languageService.getRenameInfo(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments) {
+            var _this = this;
+            return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")", function () { return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments); });
+        };
+        /// GET BRACE MATCHING
+        LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBraceMatchingAtPosition(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.isValidBraceCompletionAtPosition = function (fileName, position, openingBrace) {
+            var _this = this;
+            return this.forwardJSONCall("isValidBraceCompletionAtPosition('" + fileName + "', " + position + ", " + openingBrace + ")", function () { return _this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace); });
+        };
+        LanguageServiceShimObject.prototype.getSpanOfEnclosingComment = function (fileName, position, onlyMultiLine) {
+            var _this = this;
+            return this.forwardJSONCall("getSpanOfEnclosingComment('" + fileName + "', " + position + ")", function () { return _this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine); });
+        };
+        /// GET SMART INDENT
+        LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options /*Services.EditorOptions*/) {
+            var _this = this;
+            return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () {
+                var localOptions = JSON.parse(options);
+                return _this.languageService.getIndentationAtPosition(fileName, position, localOptions);
+            });
+        };
+        /// GET REFERENCES
+        LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getReferencesAtPosition(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.findReferences = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("findReferences('" + fileName + "', " + position + ")", function () { return _this.languageService.findReferences(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getOccurrencesAtPosition(fileName, position); });
+        };
+        LanguageServiceShimObject.prototype.getDocumentHighlights = function (fileName, position, filesToSearch) {
+            var _this = this;
+            return this.forwardJSONCall("getDocumentHighlights('" + fileName + "', " + position + ")", function () {
+                var results = _this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
+                // workaround for VS document highlighting issue - keep only items from the initial file
+                var normalizedName = ts.normalizeSlashes(fileName).toLowerCase();
+                return ts.filter(results, function (r) { return ts.normalizeSlashes(r.fileName).toLowerCase() === normalizedName; });
+            });
+        };
+        /// COMPLETION LISTS
+        /**
+         * Get a string based representation of the completions
+         * to provide at the given source position and providing a member completion
+         * list if requested.
+         */
+        LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getCompletionsAtPosition(fileName, position); });
+        };
+        /** Get a string based representation of a completion list entry details */
+        LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName, options /*Services.FormatCodeOptions*/, source) {
+            var _this = this;
+            return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () {
+                var localOptions = JSON.parse(options);
+                return _this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source);
+            });
+        };
+        LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options /*Services.FormatCodeOptions*/) {
+            var _this = this;
+            return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () {
+                var localOptions = JSON.parse(options);
+                return _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
+            });
+        };
+        LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options /*Services.FormatCodeOptions*/) {
+            var _this = this;
+            return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () {
+                var localOptions = JSON.parse(options);
+                return _this.languageService.getFormattingEditsForDocument(fileName, localOptions);
+            });
+        };
+        LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options /*Services.FormatCodeOptions*/) {
+            var _this = this;
+            return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () {
+                var localOptions = JSON.parse(options);
+                return _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
+            });
+        };
+        LanguageServiceShimObject.prototype.getDocCommentTemplateAtPosition = function (fileName, position) {
+            var _this = this;
+            return this.forwardJSONCall("getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDocCommentTemplateAtPosition(fileName, position); });
+        };
+        /// NAVIGATE TO
+        /** Return a list of symbols that are interesting to navigate to */
+        LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue, maxResultCount, fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ", " + fileName + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName); });
+        };
+        LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(fileName); });
+        };
+        LanguageServiceShimObject.prototype.getNavigationTree = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); });
+        };
+        LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); });
+        };
+        LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) {
+            var _this = this;
+            return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () { return _this.languageService.getTodoComments(fileName, JSON.parse(descriptors)); });
+        };
+        /// Emit
+        LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) {
+            var _this = this;
+            return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () { return _this.languageService.getEmitOutput(fileName); });
+        };
+        LanguageServiceShimObject.prototype.getEmitOutputObject = function (fileName) {
+            var _this = this;
+            return forwardCall(this.logger, "getEmitOutput('" + fileName + "')", 
+            /*returnJson*/ false, function () { return _this.languageService.getEmitOutput(fileName); }, this.logPerformance);
+        };
+        return LanguageServiceShimObject;
+    }(ShimBase));
+    function convertClassifications(classifications) {
+        return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState };
+    }
+    var ClassifierShimObject = /** @class */ (function (_super) {
+        __extends(ClassifierShimObject, _super);
+        function ClassifierShimObject(factory, logger) {
+            var _this = _super.call(this, factory) || this;
+            _this.logger = logger;
+            _this.logPerformance = false;
+            _this.classifier = ts.createClassifier();
+            return _this;
+        }
+        ClassifierShimObject.prototype.getEncodedLexicalClassifications = function (text, lexState, syntacticClassifierAbsent) {
+            var _this = this;
+            return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", function () { return convertClassifications(_this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)); }, this.logPerformance);
+        };
+        /// COLORIZATION
+        ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) {
+            var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
+            var result = "";
+            for (var _i = 0, _a = classification.entries; _i < _a.length; _i++) {
+                var item = _a[_i];
+                result += item.length + "\n";
+                result += item.classification + "\n";
+            }
+            result += classification.finalLexState;
+            return result;
+        };
+        return ClassifierShimObject;
+    }(ShimBase));
+    var CoreServicesShimObject = /** @class */ (function (_super) {
+        __extends(CoreServicesShimObject, _super);
+        function CoreServicesShimObject(factory, logger, host) {
+            var _this = _super.call(this, factory) || this;
+            _this.logger = logger;
+            _this.host = host;
+            _this.logPerformance = false;
+            return _this;
+        }
+        CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
+            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
+        };
+        CoreServicesShimObject.prototype.resolveModuleName = function (fileName, moduleName, compilerOptionsJson) {
+            var _this = this;
+            return this.forwardJSONCall("resolveModuleName('" + fileName + "')", function () {
+                var compilerOptions = JSON.parse(compilerOptionsJson);
+                var result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
+                var resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined;
+                if (result.resolvedModule && result.resolvedModule.extension !== ".ts" /* Ts */ && result.resolvedModule.extension !== ".tsx" /* Tsx */ && result.resolvedModule.extension !== ".d.ts" /* Dts */) {
+                    resolvedFileName = undefined;
+                }
+                return {
+                    resolvedFileName: resolvedFileName,
+                    failedLookupLocations: result.failedLookupLocations
+                };
+            });
+        };
+        CoreServicesShimObject.prototype.resolveTypeReferenceDirective = function (fileName, typeReferenceDirective, compilerOptionsJson) {
+            var _this = this;
+            return this.forwardJSONCall("resolveTypeReferenceDirective(" + fileName + ")", function () {
+                var compilerOptions = JSON.parse(compilerOptionsJson);
+                var result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
+                return {
+                    resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined,
+                    primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true,
+                    failedLookupLocations: result.failedLookupLocations
+                };
+            });
+        };
+        CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
+            var _this = this;
+            return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
+                // for now treat files as JavaScript
+                var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
+                return {
+                    referencedFiles: _this.convertFileReferences(result.referencedFiles),
+                    importedFiles: _this.convertFileReferences(result.importedFiles),
+                    ambientExternalModules: result.ambientExternalModules,
+                    isLibFile: result.isLibFile,
+                    typeReferenceDirectives: _this.convertFileReferences(result.typeReferenceDirectives)
+                };
+            });
+        };
+        CoreServicesShimObject.prototype.getAutomaticTypeDirectiveNames = function (compilerOptionsJson) {
+            var _this = this;
+            return this.forwardJSONCall("getAutomaticTypeDirectiveNames('" + compilerOptionsJson + "')", function () {
+                var compilerOptions = JSON.parse(compilerOptionsJson);
+                return ts.getAutomaticTypeDirectiveNames(compilerOptions, _this.host);
+            });
+        };
+        CoreServicesShimObject.prototype.convertFileReferences = function (refs) {
+            if (!refs) {
+                return undefined;
+            }
+            var result = [];
+            for (var _i = 0, refs_2 = refs; _i < refs_2.length; _i++) {
+                var ref = refs_2[_i];
+                result.push({
+                    path: ts.normalizeSlashes(ref.fileName),
+                    position: ref.pos,
+                    length: ref.end - ref.pos
+                });
+            }
+            return result;
+        };
+        CoreServicesShimObject.prototype.getTSConfigFileInfo = function (fileName, sourceTextSnapshot) {
+            var _this = this;
+            return this.forwardJSONCall("getTSConfigFileInfo('" + fileName + "')", function () {
+                var text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength());
+                var result = ts.parseJsonText(fileName, text);
+                var normalizedFileName = ts.normalizeSlashes(fileName);
+                var configFile = ts.parseJsonSourceFileConfigFileContent(result, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
+                return {
+                    options: configFile.options,
+                    typeAcquisition: configFile.typeAcquisition,
+                    files: configFile.fileNames,
+                    raw: configFile.raw,
+                    errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
+                };
+            });
+        };
+        CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () {
+            return this.forwardJSONCall("getDefaultCompilationSettings()", function () { return ts.getDefaultCompilerOptions(); });
+        };
+        CoreServicesShimObject.prototype.discoverTypings = function (discoverTypingsJson) {
+            var _this = this;
+            var getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
+            return this.forwardJSONCall("discoverTypings()", function () {
+                var info = JSON.parse(discoverTypingsJson);
+                if (_this.safeList === undefined) {
+                    _this.safeList = ts.JsTyping.loadSafeList(_this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
+                }
+                return ts.JsTyping.discoverTypings(_this.host, function (msg) { return _this.logger.log(msg); }, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), _this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports);
+            });
+        };
+        return CoreServicesShimObject;
+    }(ShimBase));
+    var TypeScriptServicesFactory = /** @class */ (function () {
+        function TypeScriptServicesFactory() {
+            this._shims = [];
+        }
+        /*
+         * Returns script API version.
+         */
+        TypeScriptServicesFactory.prototype.getServicesVersion = function () {
+            return ts.servicesVersion;
+        };
+        TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
+            try {
+                if (this.documentRegistry === undefined) {
+                    this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
+                }
+                var hostAdapter = new LanguageServiceShimHostAdapter(host);
+                var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
+                return new LanguageServiceShimObject(this, host, languageService);
+            }
+            catch (err) {
+                logInternalError(host, err);
+                throw err;
+            }
+        };
+        TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) {
+            try {
+                return new ClassifierShimObject(this, logger);
+            }
+            catch (err) {
+                logInternalError(logger, err);
+                throw err;
+            }
+        };
+        TypeScriptServicesFactory.prototype.createCoreServicesShim = function (host) {
+            try {
+                var adapter = new CoreServicesShimHostAdapter(host);
+                return new CoreServicesShimObject(this, host, adapter);
+            }
+            catch (err) {
+                logInternalError(host, err);
+                throw err;
+            }
+        };
+        TypeScriptServicesFactory.prototype.close = function () {
+            // Forget all the registered shims
+            ts.clear(this._shims);
+            this.documentRegistry = undefined;
+        };
+        TypeScriptServicesFactory.prototype.registerShim = function (shim) {
+            this._shims.push(shim);
+        };
+        TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
+            for (var i = 0; i < this._shims.length; i++) {
+                if (this._shims[i] === shim) {
+                    delete this._shims[i];
+                    return;
+                }
+            }
+            throw new Error("Invalid operation");
+        };
+        return TypeScriptServicesFactory;
+    }());
+    ts.TypeScriptServicesFactory = TypeScriptServicesFactory;
+    if (typeof module !== "undefined" && module.exports) {
+        module.exports = ts;
+    }
+})(ts || (ts = {}));
+/* tslint:enable:no-in-operator */
+/* tslint:enable:no-null */
+/// TODO: this is used by VS, clean this up on both sides of the interface
+/* @internal */
+var TypeScript;
+(function (TypeScript) {
+    var Services;
+    (function (Services) {
+        Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
+    })(Services = TypeScript.Services || (TypeScript.Services = {}));
+})(TypeScript || (TypeScript = {}));
+// 'toolsVersion' gets consumed by the managed side, so it's not unused.
+// TODO: it should be moved into a namespace though.
+/* @internal */
+var toolsVersion = "2.6";
diff --git a/tapestry-webresources/src/test/groovy/t5/webresources/tests/TypeScriptCompilerSpec.groovy b/tapestry-webresources/src/test/groovy/t5/webresources/tests/TypeScriptCompilerSpec.groovy
new file mode 100644
index 0000000..aafd30a
--- /dev/null
+++ b/tapestry-webresources/src/test/groovy/t5/webresources/tests/TypeScriptCompilerSpec.groovy
@@ -0,0 +1,58 @@
+package t5.webresources.tests;
+
+import org.apache.tapestry5.SymbolConstants
+import org.apache.tapestry5.internal.InternalSymbols
+import org.apache.tapestry5.internal.test.PageTesterContext
+import org.apache.tapestry5.internal.webresources.TypeScriptCompiler
+import org.apache.tapestry5.ioc.MappedConfiguration
+import org.apache.tapestry5.ioc.annotations.Autobuild
+import org.apache.tapestry5.ioc.annotations.Inject
+import org.apache.tapestry5.ioc.annotations.SubModule
+import org.apache.tapestry5.ioc.internal.util.ClasspathResource
+import org.apache.tapestry5.modules.AssetsModule
+import org.apache.tapestry5.modules.TapestryModule
+import org.apache.tapestry5.services.ApplicationGlobals
+import org.apache.tapestry5.webresources.modules.WebResourcesModule
+
+import spock.lang.Shared
+import spock.lang.Specification
+
+@SubModule([TapestryModule, WebResourcesModule, TypeScriptCompilerSpec.TestModule, AssetsModule])
+class TypeScriptCompilerSpec extends Specification {
+
+  @Autobuild
+  private TypeScriptCompiler typeScriptCompiler;
+
+  @Inject
+  @Shared
+  private ApplicationGlobals applicationGlobals
+
+  def setupSpec(){
+    applicationGlobals.storeContext(new PageTesterContext("/test"));
+  }
+
+  def "Compile Hello World example"(){
+    when:
+    def resource = new ClasspathResource("t5/webresources/greeter.ts")
+    def compiled = typeScriptCompiler.transform(resource, null)
+    then:
+    compiled.text == TypeScriptCompilerSpec.class.getResourceAsStream('/t5/webresources/greeter-compiled.js').text
+  }
+
+  def "Type information is preserved"(){
+    when:
+    def resource = new ClasspathResource("t5/webresources/park-example.ts")
+    def compiled = typeScriptCompiler.transform(resource, null)
+    then:
+    compiled.text == TypeScriptCompilerSpec.class.getResourceAsStream('/t5/webresources/park-example-compiled.js').text
+  }
+  
+  public static class TestModule {
+
+    def contributeApplicationDefaults(MappedConfiguration configuration){
+      configuration.add(InternalSymbols.APP_NAME, "test")
+      configuration.add("tapestry.app-package", "typescript")
+      configuration.add(SymbolConstants.MINIFICATION_ENABLED, false)
+    }
+  }
+}
diff --git a/tapestry-webresources/src/test/resources/t5/webresources/greeter-compiled.js b/tapestry-webresources/src/test/resources/t5/webresources/greeter-compiled.js
new file mode 100644
index 0000000..0794189
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/t5/webresources/greeter-compiled.js
@@ -0,0 +1,8 @@
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    function greeter(person) {
+        return "Hello, " + person;
+    }
+    var user = "Jane User";
+    document.body.innerHTML = greeter(user);
+});
diff --git a/tapestry-webresources/src/test/resources/t5/webresources/greeter.ts b/tapestry-webresources/src/test/resources/t5/webresources/greeter.ts
new file mode 100644
index 0000000..7fc2d1a
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/t5/webresources/greeter.ts
@@ -0,0 +1,7 @@
+function greeter(person) {
+    return "Hello, " + person;
+}
+
+var user = "Jane User";
+
+document.body.innerHTML = greeter(user);
\ No newline at end of file
diff --git a/tapestry-webresources/src/test/resources/t5/webresources/park-example-compiled.js b/tapestry-webresources/src/test/resources/t5/webresources/park-example-compiled.js
new file mode 100644
index 0000000..6d8e725
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/t5/webresources/park-example-compiled.js
@@ -0,0 +1,26 @@
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    var Pterodactyls = /** @class */ (function () {
+        function Pterodactyls() {
+        }
+        return Pterodactyls;
+    }());
+    var Park = /** @class */ (function () {
+        function Park(x, y) {
+        }
+        Park = __decorate([
+            Aviary,
+            __metadata("design:paramtypes", [Pterodactyls, String])
+        ], Park);
+        return Park;
+    }());
+});
diff --git a/tapestry-webresources/src/test/resources/t5/webresources/park-example.ts b/tapestry-webresources/src/test/resources/t5/webresources/park-example.ts
new file mode 100644
index 0000000..ce9b4f2
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/t5/webresources/park-example.ts
@@ -0,0 +1,6 @@
+class Pterodactyls {}
+
+@Aviary
+class Park {
+  constructor(x: Pterodactyls, y: string) {}
+}
\ No newline at end of file
